Python 将UTF bytestream强制为ASCII
我知道Python 将UTF bytestream强制为ASCII,python,csv,python-2.7,Python,Csv,Python 2.7,我知道csv不会直接处理UTF,解决方案的一部分是使用codecs打开文件,使用正确的编码打开流。但是,我仍然得到错误: UnicodeEncodeError: 'ascii' codec can't encode character u'\xed' in position 121: ordinal not in range(128) 是否有一种方法可以处理来自infle的字节流,将其强制转换为ascii,然后再将其移交给csv.DictReader?谢谢 with( codecs.ope
csv
不会直接处理UTF,解决方案的一部分是使用codecs
打开文件,使用正确的编码打开流。但是,我仍然得到错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xed' in position 121: ordinal not in range(128)
是否有一种方法可以处理来自infle的字节流,将其强制转换为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)
问题不在于“csv
不会直接处理UTF”;Python中没有任何东西可以直接处理UTF,您也不希望它这样做。如果需要Unicode,则使用Unicode;当需要特定编码(无论是UTF-8、UTF-16还是其他编码)时,必须使用字符串并手动跟踪编码
Python2.x
csv
无法处理Unicode,因此排除了简单的方法。事实上,它只理解字节字符串,并且总是将它们视为ASCII。但是,除了它关心的特定字符(分隔符、引号、换行符等)之外,它不会篡改任何内容。因此,只要您使用的字符集的、
、“
”和\n
(或您选择的任何特殊字符)保证编码到与ASCII相同的字节,并且不会将任何其他字符编码到这些字节,就可以了
当然,您不只是想在任意字符集中创建CSV文件;您可能想在其他程序Excel中使用它,在某个服务器上运行的脚本,无论什么,您都需要在其他程序期望的字符集中创建CSV文件。但是如果您可以控制其他程序(例如,它是Excel,并且您知道如何在其导入命令中选择字符集),UTF-8几乎总是最佳选择
无论如何,UTF-16不符合CSV友好字符集的条件,因为,例如,,
是两个字节,而不是一个字节
那么,您如何处理这个问题呢?文档中的有答案。如果您只是复制
unicode\u csv\u reader
函数并将其与编解码器一起使用。打开,您就完成了。或者复制UnicodeReader
类并将其传递给编码
但是,如果你阅读示例代码,你会发现它是多么微不足道:解码UTF-16,重新编码为UTF-8,然后将其传递给读卡器
或读卡器
。你可以将其减少为一行额外的代码,(line.encode('UTF-8')用于内嵌的行)
。因此:
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。csv
模块仍然只处理ByTestRing;它试图将unicode值编码回字节字符串。换句话说,您的方法永远不会起作用。请使用常规的Open()
将文件作为ByTestStream打开您的意思是“删除任何非7位字符”,这并不难做到。提示:ord()
@MartijnPieters:用常规的open
打开它是行不通的。csv
只处理ASCII兼容的字节字符串;UTF-16不合格。@abarnert:是的,我意识到了;我正在考虑把它当作一个复制品。谢谢abarnert,Martijn。这太费劲了;我对编码处理的想法已经结束了。我会的逐步完成这个过程。@user2808321:您几乎总是必须仔细考虑编码过程,尤其是当您的输入和输出字符集是非ASCII友好的,如UTF-16时。当然,除非您升级到Python 3.x。