如何将python csv.DictReader与二进制文件一起使用?(用于babel自定义提取方法)

tia*_*lva 1 python csv babel python-3.x

我正在尝试为babel编写自定义提取方法,以从csv文件中的特定列提取字符串。我在这里关注了文档。

这是我的提取方法代码:

def extract_csv(fileobj, keywords, comment_tags, options):
    import csv
    reader = csv.DictReader(fileobj, delimiter=',')
    for row in reader:
        if row and row['caption'] != '':
            yield (reader.line_num, '', row['caption'], '')
Run Code Online (Sandbox Code Playgroud)

当我尝试运行提取时,出现此错误:

在extract_csv中第18行的“ /Users/tiagosilva/repos/naltio/csv_extractor.py”文件中,用于读取器中的行:文件“ /usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6” /lib/python3.6/csv.py”,下一个 self.fieldnames文件中的第111行,“ / usr / local / Cellar / python / 3.6.5 / Frameworks / Python.framework / Versions / 3.6 / lib / python3.6 /csv.py”,第98行,字段名称为self._fieldnames = next(self.reader)_csv.Error:迭代器应返回字符串,而不是字节(您是否以文本模式打开文件?)

似乎传递给函数的fileobj是在二进制模式下打开的。

如何使这项工作?我可以想到2种可能的解决方案,但我不知道如何编写它们:

1)是否可以在DictReader中使用它?

2)有没有一种方法可以通知babel以文本模式打开文件?

我愿意接受其他未列出的解决方案。

tia*_*lva 8

我实际上找到了一种方法!

解决方案1是一种处理二进制文件的方法。解决方案是将TextIOWrapper包装在二进制文件周围,并对其进行解码,然后将其传递给DictReader。

import csv
import io

with io.TextIOWrapper(fileobj, encoding='utf-8') as text_file:
    reader = csv.DictReader(text_file, delimiter=',')

    for row in reader:
        if row and 'caption' in row.keys():
            yield (reader.line_num, '', row['caption'], '')
Run Code Online (Sandbox Code Playgroud)

  • 万一它对其他人有帮助:如果您有一个包含一个或多个 csv 文件的 zip 文件,并且使用的是仅支持以二进制模式打开的 python 3.6+ zipfile(可能更旧),那么这种方法也很有效 (3认同)
  • 这个紧凑的解决方案解决了我面临的问题,其中未知文件 blob 已作为二进制文件打开,但如果它实际上是 CSV,则需要作为文本处理(并且我无法更改它最初摄取的方式)。我见过的所有其他答案都改变了您打开它的方式,而不是您处理它的方式。 (2认同)