【问题标题】:How do I read in a CSV file that contains pound symbols?如何读取包含英镑符号的 CSV 文件?
【发布时间】:2016-01-11 11:01:04
【问题描述】:

我的文件在开头有一个 NUL 字节,我很纠结“£”符号

data_initial = codecs.open(filename, "rU", "utf-16")
data = csv.DictReader((line.replace('\x00','') for line in data_initial), delimiter="\t")
    for row in data:
        print row

我得到错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in 位置 169:序数不在范围内(128)

顺便说一句:我是否尝试打印此行并不重要。我可以只打印 '1' 并且错误保持不变。我不知道为什么它说这是一个编码错误,而它可能是一个解码错误。

无论如何,我该如何处理这个问题?

【问题讨论】:

    标签: python encoding


    【解决方案1】:

    问题几乎可以肯定是codecs.open(filename, "rU", "utf-16") 正在以与csv 不兼容的方式转换“£”符号:

    此版本的 csv 模块不支持 Unicode 输入。此外,目前还有一些关于 ASCII NUL 字符的问题。因此,为了安全起见,所有输入都应该是 UTF-8 或可打印的 ASCII;请参阅示例部分中的示例。

    只需将编码类型更改为“utf-8”(假设文件中没有不兼容的符号)即可解决问题:codecs.open(filename, "rU", "utf-8")

    【讨论】:

    • 我尝试将文件转换为UTF-8,但结果是一样的。如何用不同的符号替换 £?
    【解决方案2】:

    我假设您在这里使用的是 Python 2.7。在 Python 2.7 下,CSV 不支持 python unicode 字符串。您必须以原始二进制文件读取文件,然后解码字符串 after csv 返回它们。您无法在读取文件时对其进行解码并期望 csv 来处理它;我的经验是它无法应付。

    这在 Python 3.x 中非常不同,其中 csv 确实支持 Unicode,您必须在 csv 读取数据之前进行解码。否则就不行了。

    这两种情况之间有如此大的差异有点令人讨厌。

    我使用所有 Python 版本的旧但经过测试的代码看起来像(怀疑你应该能够用你想要的任何东西替换“ascii”)。是的,只是注意到一些断言有点毫无意义,但无论如何都要在此处引用原始测试代码。

    if sys.version_info < (3, 0):
        # Python2: csv module does not support unicode, we must use byte strings.   
    
        def _input_csv(csv_data):
            for line in csv_data:
                assert isinstance(line, bytes)
                yield line
    
        def _output_csv(csv_line):
            for i, column in enumerate(csv_line):
                csv_line[i] = column.decode("ascii", errors='ignore')
                assert isinstance(csv_line[i], unicode)  # NOQA
    
    else:
        # Python3: csv module does support unicode, we must use strings everywhere, 
        # not byte strings
    
        def _input_csv(unicode_csv_data):
            for line in unicode_csv_data:
                assert isinstance(line, bytes)
                line = line.decode("ascii", errors='ignore')
                assert isinstance(line, str)
                yield line
    
        def _output_csv(csv_line):
            for column in csv_line:
                assert isinstance(column, str)
    

    我在哪里读取(在这种情况下是从一个子进程):

    reader = csv.reader(_input_csv(process.stdout), delimiter="|")
    for row in reader:
        _output_csv(row)
    

    【讨论】:

    • 我无法对上述回复发表评论 - 我没有足够的声誉 - 但是我注意到 codecs.open(filename, "rU", "utf-8") 不起作用 - 读取 UTF-8 字符串并将它们转换为 python Unicode 字符串。结果 csv 看不到它需要的 UTF-8 数据。
    猜你喜欢
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多