【问题标题】:Using r+ mode to read and write into the same file使用r+模式读写同一个文件
【发布时间】:2016-04-14 11:42:02
【问题描述】:

我有一个脚本可以成功地从 csv 文件中删除一列。目前它通过创建一个新文件来做到这一点。我希望它写入原始文件而不是创建一个新文件。 我已经尝试过使用 r+ 模式打开,但它没有按我想要的方式工作。请参阅下面的注释。我认为 r+ 模式是我需要的模式,但我正在努力寻找可行的示例来学习。

我的代码:

    import csv

    in_file = "Path to Source"
    out_file = "Path to Result"

    with open(in_file, 'r', newline='') as inf, \
        open(out_file, 'w', newline='') as outf:
     reader = csv.reader(inf)
     writer = csv.writer(outf)

     for r in reader:
         writer.writerow((r[0],r[1],r[2],r[3],r[4],r[5],r[6]))

尝试使用r+模式:

with open(in_file, 'r+', newline='') as inf:
    reader = csv.reader(inf)
    writer = csv.writer(inf)

    for r in reader:
        writer.writerow((r[0],r[1],r[2],r[3],r[4],r[5],r[6]))

这会失败并出现错误list index out of range

【问题讨论】:

  • 据我所见,当读者阅读时,作者在写作。文件有一个“光标”,即读取/写入文件的当前位置。所以作者正在覆盖读者刚刚阅读的那一行之后的下一行。为什么不创建一个新文件然后重命名它?

标签: python file csv io


【解决方案1】:

据我所知,当读者阅读时,作者在写作。在同一个文件上。

文件有一个“光标”,即读取/写入文件的当前位置。

因此,写入者正在覆盖文件中读取者刚刚读取的行之后的下一行,从而对后续读取造成灾难性后果。

我认为第一种方法最好:新建一个文件,然后重命名(原来的输入文件会被自动删除)

import csv, os
in_file = "Path to Source"
out_file = "Path to Result"

with open(in_file, 'r', newline='') as inf, \
     open(out_file, 'w', newline='') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf)
    for r in reader:
        writer.writerow(r[:7])

os.rename(out_file, in_file)

【讨论】:

  • 谢谢宾奇亚。当文件存在时出现错误无法重命名,因此在 os.rename(out_file, in_file) 之前插入了 os.remove(in_file) 并且现在可以正常工作。感谢您的帮助。
  • @bassmann:由于您使用的是newline='',我猜您使用的是 Python 3。如果是这种情况(并且您使用的是 3.3 或更高版本),您可以使用 @ 987654321@,在 Linux 和 Windows 上具有一致的替换行为(在没有提示的情况下替换现有文件)。避免与删除然后重命名有关的竞争条件。
猜你喜欢
  • 2013-07-06
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 2012-12-29
  • 2016-05-09
  • 1970-01-01
  • 2016-01-14
相关资源
最近更新 更多