10

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

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

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

请注意,insert在此用例中,将每个值行放在列表中,然后将列表内爆不是可行的解决方案。

4

4 回答 4

9

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

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

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

于 2013-06-10T12:03:55.000 回答
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 表示法逻辑封装到一个类中,保持代码可读性,同时简化调用者代码。

于 2013-06-10T12:04:35.910 回答
0

尝试打开文件以二进制形式写入:'wb' 而不是 'w'。

于 2013-06-10T11:57:20.847 回答
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)
于 2013-06-10T12:26:08.463 回答