【问题标题】:CSV reader object not reading entire file [Python]CSV 阅读器对象未读取整个文件 [Python]
【发布时间】:2013-11-12 23:40:17
【问题描述】:

我目前正在做一个在 python 中使用 csv 模块的项目。我创建了一个单独的类来打开一个预先存在的 csv 文件,修改每一行的数据,然后将数据保存到一个新的 csv 文件中。

原始文件有 1438 行,通过将一些测试代码放入处理写入的类中,表明它正在向新的 csv 文件写入 1438 行。在检查文件本身后,新创建的文件中实际上有 1438 行。但是,当我以这种方式使用标准 cvs 模块时:

reader = csv.reader(open('naiveData.csv', 'rb'))

它只转到第 1410 行(甚至不是整行,它在行尾之前结束一个半索引。我不确定是什么原因造成的。

这是我访问阅读器的方式:

 for row in reader:                                                          
    print row 

这是失败的输出部分:

['UNPM', '16', '2.125', '910', 'athlete', 'enrolled'] 
['UNPM', '14', '2.357', '1020', 'non-athlete', 'enrolled']    
['UNDC', '17', '2.071', '910', 'athlete', 'unenrolled']  
['KINS', '15', '2.6', '910', 'athlete', 'enrolled']  
['PHYS', '16', '1.5', '900', 'non-']

最后一个列表应该有 ['PHYS', '16', '1.5', '900', 'non-athlete', 'enrolled']。

关于可能导致此问题的任何想法?提前致谢!

编辑:

以下是 CVS 文件中发生错误的区域周围的行:

KINS,15,2.6,910,athlete,enrolled
PHYS,16,1.5,900,non-athlete,enrolled
UNPL,15,3,960,non-athlete,enrolled

【问题讨论】:

  • 你能从输出中断的输入文件中发布完整的行吗?
  • @PedroWerneck 确定,我在问题底部添加了它
  • 所以你在做 read_csv(x) -> process -> write_csv(y),然后当你再次 read_csv(y) 读取行时,有些丢失了?
  • 在您阅读时文件似乎没有完全刷新到磁盘。你在使用 with 语句吗?写入后是否正确关闭?
  • 写文件时,是显式调用.close() 还是使用with 语句来确保文件正确关闭?我想知道在你的写作程序终止之前文件是否没有被完全写入。如果您使用的是 CPython,这似乎不太可能,但如果您使用的是 Jython 或 PyPy,这似乎是可能的。

标签: python csv


【解决方案1】:

我敢打赌这是问题所在,尽管很难确定您何时只向我们展示了 3 行代码而不是可重现的示例。

你正在做这样的事情:

old_reader = csv.reader(open('old.csv', 'rb'))
writer = csv.writer(open('new.csv', 'wb'))
for row in old_reader:
    writer.writerow(transform(row))
new_reader = csv.reader(open('new.csv', 'rb'))
for row in new_reader:
    print row

在您打开new.csv 进行阅读时,您还没有关闭new.csv 进行写作。所以最后一个缓冲区还没有被刷新到磁盘。所以你看不到它。

但是,当您的脚本完成时,writer 超出范围,文件对象不再有任何引用,因此它被刷新并关闭。因此,当您从程序外部检查它时,脚本完成后,它就完成了。 (请注意,这种行为并不能得到明确保证;你只是走运了。)

这就是为什么您永远不应该通过将open 放在表达式中间来泄漏文件的原因。请改用with 语句。例如:

with open('old.csv', 'rb') as oldf, open('new.csv', 'wb') as newf:
    old_reader = csv.reader(oldf)
    writer = csv.writer(newt)
    for row in old_reader:
        writer.writerow(transform(row))
with open('new.csv', 'rb') as newf:
    new_reader = csv.reader(newf)
    for row in new_reader:
        print row

【讨论】:

  • 非常感谢您的解释!它工作得很好。下次我会牢记使用 with 语句的概念。
  • 这也是通过 subprocess.Popen 发生在我身上的,它有一个生成 csv 文件的进程。用 run() 替换 Popen() 调用解决了这个问题(python 3.5.2)
【解决方案2】:

我遇到了类似的问题,但最终问题是 csv 文件的一行中缺少逗号

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多