写入文件的最后一个字符的“Backspace”

时间:2013-06-10 11:53:55

标签: python

我有一个输出SQL文件的Python应用程序:

sql_string = "('" + name + "', " + age + "'),"
output_files['sql'].write(os.linesep + sql_string)
output_files['sql'].flush()

这不是在for循环中完成的,它是在数据可用时编写的。当应用程序运行完毕后,有没有办法对最后一个逗号字符进行'退格',并用分号替换它?我确信我可以通过在换行符之前输出逗号来创建一些解决方法,并使用全局Bool来确定是否有任何特定的“写入”是第一次写入。但是,我认为如果我可以对它进行'退格',应用程序会更加清晰。当然,作为Python可能有这么简单的方法!

请注意,在此用例中,在列表中包含每个insert值行,然后对列表进行内爆是不可行的。

4 个答案:

答案 0 :(得分:8)

使用seek将光标向后移动一个字节(字符),然后写入新字符:

f.seek(-1, os.SEEK_CUR)
f.write(";")

这是最简单的更改,维护您当前的代码(“工作代码”胜过“理想代码”),但最好避免这种情况。

答案 1 :(得分:4)

在添加新行之前添加逗号怎么样?

first_line = True

...

sql_string = "('" + name + "', " + age + "')"

if not first_line:
    output_files['sql'].write(",")
first_line = False

output_files['sql'].write(os.linesep + sql_string)
output_files['sql'].flush()

...

output_files['sql'].write(";")
output_files['sql'].flush()

你确实在你的问题中提到了这一点 - 我认为维护者比寻找逗号并覆盖它们要清楚得多。

编辑:由于上面的解决方案需要在代码中使用全局布尔值(这是不可取的),您可以将文件写入行为包装到辅助类中:

class SqlFileWriter:

    first_line = True

    def __init__(self, file_name):
        self.f = open(file_name)

    def write(self, sql_string):
        if not self.first_line:
            self.f.write(",")
        self.first_line = False

        self.f.write(os.linesep + sql_string)
        self.f.flush()

    def close(self):
        self.f.write(";")
        self.f.close()


output_files['sql'] = SqlFileWriter("myfile.sql")
output_files['sql'].write("('" + name + "', '" + age + "')")

这将所有SQL表示法逻辑封装到一个类中,保持代码可读,同时简化调用者代码。

答案 2 :(得分:0)

尝试打开文件写为二进制文件:'wb'而不是'w'。

答案 3 :(得分:0)

使用生成器,例如:

def with_separator(data, sep):
    first = True:
    for datum in data:
        if first:
            first = False
        else:
            yield sep
        yield datum

with open("sdfasdfas", "w") as outf:
    for x in with_separator(sql_get_rows(), ",\n"):
        outf.write(x)
        # flush if needed

对于硬核迭代器的使用,这应该让你开始:

In [11]: list( itertools.imap("".join, itertools.izip(itertools.chain([""], itertools.repeat(",\n")), "abc")) )
Out[11]: ['a', ',\nb', ',\nc']

如果您的数据使用命令式API,那是不可迭代的,send()您的数据生成器:

def write_with_separator(filename, sep):
    with file(filename, "w"):
        first = True
        yield None
        while True:
            datum = yield None
            if first:
                first = False
            else:
                fout.write(sep)
            fout.write(datum)
            # flush if needed

writer = write_with_separator("somefilename", ",\n")
writer.next()  # can't send to just-started generator

# to be called when you get data
for row in sql_get_rows():
    writer.send(row)