我有一个输出SQL文件的Python应用程序:
sql_string = "('" + name + "', " + age + "'),"
output_files['sql'].write(os.linesep + sql_string)
output_files['sql'].flush()
这不是在for
循环中完成的,它是在数据可用时编写的。当应用程序运行完毕后,有没有办法对最后一个逗号字符进行'退格',并用分号替换它?我确信我可以通过在换行符之前输出逗号来创建一些解决方法,并使用全局Bool来确定是否有任何特定的“写入”是第一次写入。但是,我认为如果我可以对它进行'退格',应用程序会更加清晰。当然,作为Python可能有这么简单的方法!
请注意,在此用例中,在列表中包含每个insert
值行,然后对列表进行内爆是不可行的。
答案 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)