为什么f.write会在elif语句后覆盖一行?

时间:2016-12-22 21:46:26

标签: python python-2.7

我已经问过这个问题here,但我认为我不够清楚,最终被关闭了。我正在尝试打开一个文件进行写入,如果已经存在则覆盖,通过调用f.write根据不同的条件写入多行,然后关闭它。我知道使用f = open(path, "a")进行追加,但我希望第一次覆盖该文件而a不会这样做。

理想情况下,如果我有这样的东西,我会得到类似于我想要的输出的东西,如果它存在则覆盖文件并通过调用f.write

添加行
def cell_clicked(self, item):
    if item.checkState() == QtCore.Qt.Checked:
        name = self.table
        header = name.horizontalHeaderItem(item.column()).text()
        path = '/home/user/file.txt'

        f = open(path, "w")
        if header == "c1":
            f.write('%s\n' % name.item(item.row(), 0).text())
            f.write("In new new line\n")
            # I'd get 2 lines whooo!
    else:
        print('%s' % item.text())
        print (item.row(),item.column())

但是,我正在使用的是它,它会在条件发生变化后覆盖文件和行。

def cell_clicked(self, item):
    if item.checkState() == QtCore.Qt.Checked:
        name = self.table
        header = name.horizontalHeaderItem(item.column()).text()
        path = '/home/user/file.txt'

        f = open(path, "w")
        if header == "c1":
            f.write('%s\n' % name.item(item.row(), 0).text())
        elif header == "c2":
            f.write('%s\n' % name.item(item.row(), 0).text())
            #unfortunately when condition changes and header is equal to c2, it overwrites the previous line
        f.close()

    else:
        print('%s' % item.text())
        print (item.row(),item.column())

3 个答案:

答案 0 :(得分:4)

您可以在set方法中定义“已写入文件”__init__

self.__already_written_to = set()

然后用以下代码替换您的open代码:

if path in self.__already_written_to:
   mode = "a"
else:
   mode = "w"
   self.__already_written_to.add(path)
with open(path, mode) as f:
    if header == "c1":
        f.write('%s\n' % name.item(item.row(), 0).text())

(无需关闭文件,因为它在退出with区块时自动完成)

所以第一次,文件将被截断,因为path从未被写入,但程序通过向集合添加path来注意到这一点。 在下一次调用时,程序会记住文件中有内容,并附加到其中。

我已经做到了它可以处理多个文件名,不仅是你在例子中提到的固定文件名,否则它甚至更简单,只是一个布尔类成员可以采取相同的行动。

答案 1 :(得分:0)

你的第二个例子在写完每一行后关闭文件;下一个调用将重新打开文件,再次从字节0开始。

解析打开/关闭逻辑,或以追加模式打开文件。

答案 2 :(得分:0)

弗朗索瓦'通过在我的 init 中声明一个布尔self.isWrittenTo = False然后根据需要调用它,这个回答给了我这样做的想法

if self.isWrittenTo:
    mode = "a"
else:
    mode = "w"
    self.isWrittenTo = True

with open(path, mode)           
    if header == "c1":
        f.write('%s\n' % name.item(item.row(), 0).text())
    elif header == "c2":
        f.write('%s\n' % name.item(item.row(), 0).text())