0

我知道它csv不会直接处理 UTF,解决方案的一部分是打开文件,使用codecs该文件使用正确的编码打开流。但是,我仍然收到错误消息:

 UnicodeEncodeError: 'ascii' codec can't encode character u'\xed' in position 121: ordinal not in range(128)

有没有办法处理来自 infile 的字节流,在移交给它之前将其强制转换为 ascii csv.DictReader?谢谢。

 with( codecs.open( infileName , 'rU', 'utf-16') ) as infile:
     rdr = csv.DictReader( infile , delimiter='\t' )
     vnames = rdr.fieldnames
     for row in rdr:
         do_something(row)
4

1 回答 1

1

问题不在于“csv不会直接处理 UTF”;Python 中的任何内容都没有直接处理 UTF,而且您不希望它这样做。当你想要 Unicode 时,你使用 Unicode;当您需要特定的编码(无论是 UTF-8、UTF-16 还是其他)时,您必须使用字符串并手动跟踪编码。


Python 2.xcsv不能处理 Unicode,所以排除了简单的方法。实际上,它只理解 bytes 字符串,并且总是将它们视为 ASCII。但是,除了它关心的特定字符(分隔符、引号、换行符等)之外,它不会篡改任何内容。因此,只要您使用一个字符集,其,, ", 和\n(或您选择的任何特殊字符)保证被编码为与 ASCII 相同的字节,并且不会将任何其他内容编码为这些字节,您就是美好的。

当然,您不只是想以任意字符集创建 CSV 文件;您可能想在其他程序中使用它——Excel,在某处的服务器上运行的脚本,等等——并且您需要在其他程序期望的字符集中创建一个 CSV 文件。但是,如果您可以控制其他程序(例如,它是 Excel,并且您知道如何在其 Import 命令中选择字符集),那么 UTF-8 几乎总是最佳选择。

无论如何,UTF-16 不符合 CSV 友好字符集的条件,因为例如,,它是两个字节,而不是一个。


那么,您如何处理呢?文档中的示例有答案。如果您只是复制该unicode_csv_reader功能并与 一起使用codecs.open,您就完成了。或者复制UnicodeReader课程并将其传递给encoding.

但是,如果您阅读示例代码,您会发现它是多么简单:解码您的 UTF-16,重新编码为 UTF-8,然后将其传递给readeror DictReader。您可以将其减少为一行额外的代码,(line.encode('utf-8') for line in infile). 所以:

with codecs.open(infileName , 'rU', 'utf-16') as infile:
    utf8 = (line.encode('utf-8') for line in infile)
    rdr = csv.DictReader(utf8, delimiter='\t')
    vnames = rdr.fieldnames
    for row in rdr:
        do_something(row)

最后,为什么您现有的代码会引发该异常?它不在 UTF-16 解码中。这是因为您将生成的unicode字符串传递给需要字节的代码str。在 Python 2.x 中,这几乎总是意味着使用默认编码自动对其进行编码,默认为 ASCII,这就是引发错误的原因。这就是为什么您必须明确编码为 UTF-8。

于 2013-10-01T18:11:16.977 回答