【问题标题】:How to use python csv.DictReader with a binary file? (For a babel custom extraction method)如何将 python csv.DictReader 与二进制文件一起使用? (对于一个 babel 自定义提取方法)
【发布时间】:2018-12-11 14:48:45
【问题描述】:

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

这是我的提取方法代码:

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'], '')

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

文件“/Users/tiagosilva/repos/naltio/csv_extractor.py”,第 18 行,在 extract_csv 中 对于阅读器中的行: 下一步中的文件“/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/csv.py”,第 111 行 self.fieldnames 文件“/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 以文本模式打开文件?

我对其他未列出的解决方案持开放态度。

【问题讨论】:

    标签: python python-3.x csv python-babel


    【解决方案1】:

    我真的找到了办法!

    这是解决方案 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'], '')
    

    【讨论】:

    • 如果它可以帮助其他人:如果您有一个包含一个或多个 csv 文件的 zip 文件并且使用仅支持以二进制打开的 python 3.6+ zipfile(可能更旧),这种方法也很有效模式
    • 这个紧凑的解决方案解决了我面临的问题,其中一个未知的文件 blob 已作为二进制文件打开,但如果它实际上是 CSV,则需要作为文本处理(我无法更改如何它最初是摄入的)。我看到的所有其他答案都会改变你打开它的方式,而不是你处理它的方式。
    • 感谢您在这里发布您的解决方案!
    • 我今天为此哭了,这个解决方案成功了! :D 非常感谢您发布解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2016-08-15
    • 2021-03-30
    • 1970-01-01
    • 2017-05-11
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多