【问题标题】:Using Python csv module on updating file使用 Python csv 模块更新文件
【发布时间】:2010-01-04 18:19:42
【问题描述】:

我正在使用 python 的 csv 模块从外部工具不断更新的 csv 中提取数据。我遇到了一个问题,当我到达文件末尾时出现 StopIteration 错误,但是,我希望脚本继续循环等待外部工具添加更多行。

到目前为止,我想出的是:

f = open('file.csv')
csvReader = csv.reader(f, delimiter=',')
while 1:
    try:
        doStuff(csvReader.next())
    except StopIteration:
        depth = f.tell()
        f.close()
        f = open('file.csv')
        f.seek(depth)
        csvReader = csv.reader(f, delimiter=',')

这具有预期的功能,但看起来也很糟糕。在捕获 StopIteration 之后循环是不可能的,因为一旦抛出 StopIteration,它将在每次后续调用 next() 时抛出一个 StopIteration。任何人对如何实现这一点有任何建议,这样我就不必做这种愚蠢的告诉和寻求?或者有一个不同的 python 模块可以轻松支持此功能。

【问题讨论】:

    标签: python file csv


    【解决方案1】:

    您的问题不在于 CSV 阅读器,而在于文件对象本身。您可能仍然需要在上面的 sn-p 中进行疯狂的旋转,但最好创建一个文件对象包装器或子类来为您完成它,并将其与您的 CSV 阅读器一起使用。这样可以将复杂性与您的 csv 处理代码隔离开来。

    例如(警告:未经测试的代码):

    class ReopeningFile(object):
        def __init__(self, filename):
            self.filename = filename
            self.f = open(self.filename)
    
        def next(self):
            try:
                self.f.next()
            except StopIteration:
                depth = self.f.tell()
                self.f.close()
                self.f = open(self.filename)
                self.f.seek(depth)
                # May need to sleep here to allow more data to come in
                # Also may need a way to signal a real StopIteration
                self.next()
    
        def __iter__(self):
            return self
    

    然后您的主代码变得更简单,因为它不必管理文件重新打开(请注意,您也不必在文件重新启动时重新启动 csv_reader:

    import csv
    csv_reader = csv.reader(ReopeningFile('data.csv'))
    for each in csv_reader:
        process_csv_line(each)
    

    【讨论】:

      【解决方案2】:

      生产者-消费者的东西可能会有点棘手。使用查找和读取字节怎么样?使用命名管道怎么样?

      哎呀,为什么不通过本地套接字进行通信?

      【讨论】:

      • +1:命名管道。放弃文件。为此目的使用更简单的东西。
      【解决方案3】:

      您很少需要显式捕获StopIteration。这样做:

      for row in csvReader:
          doStuff(row)
      

      至于检测何时将新行写入文件,您可以打开一个tail -f 进程或写出tail -f 所做的Python 代码。 (它并不复杂;它基本上只是每秒stats 文件,看看它是否改变了。Here's the C source code of tail.

      编辑:令人失望的是,在 Python 2.x 中弹出tail -f 并没有像我预期的那样工作。似乎使用fread 和一个较大的缓冲区来实现对文件行的迭代,即使该文件应该是无缓冲的(例如当 subprocess.py 创建文件时,传递 bufsize=0)。但是弹出tail 无论如何都会是一个有点丑陋的黑客。

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 2020-08-30
        • 2013-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多