处理 Python 中 non-ASCII 个字符的可靠方法?

Reliable way of handling non-ASCII characters in Python?

我有一列电子表格,其 header 包含 non-ASCII 个字符,因此:

'Campaign'

如果我将这个字符串弹出到解释器中,我得到:

'\xc3\xaf\xc2\xbb\xc2\xbfCampaign'

字符串是csv.DictReader()

rows中的键之一

当我尝试使用此键的 value 填充新字典时:

spends['Campaign'] = 2

我得到:

Key Error: '\xc3\xaf\xc2\xbb\xc2\xbfCampaign'

如果我打印行的键的值,我可以看到它是 '\xef\xbb\xbfCampaign'

显然我可以更新我的程序来访问这个密钥:

spends['\xef\xbb\xbfCampaign']

但是在 Python 中有 "better" 的方法吗?实际上,如果此键的值每次都更改为包含其他 non-ASCII 个字符,那么 all-encompassing 处理可能出现的所有 non-ASCII 个字符的方法是什么?

一般来说,您应该在输入时尽快使用相应的字符编码将字节串解码为 Unicode 文本。并且,反过来,在输出时尽可能晚地将 Unicode 文本编码为字节串。 io.open() 等一些 API 可以隐式执行此操作,以便您的代码只能看到 Unicode。

不幸的是,csv 模块在 Python 上不直接支持 Unicode 2。参见 UnicodeReader, UnicodeWriter in the doc examples。您可以为 csv.DictReader 创建它们的模拟,或者作为替代方案,只需将 utf-8 编码的字节串传递给 csv 模块。

您的具体问题是文件的前三个字节,"\xef\xbb\xbf"。这是 字节顺序掩码 的 UTF-8 编码,并且通常添加到文本文件前面以表明它们是使用 UTF-8 编码的。你应该剥离这些字节。参见 Removing BOM from gzip'ed CSV in Python

其次,您使用了错误的编解码器进行解码。 "" 是使用 Windows-1252 字符集解码这些字节时得到的结果。这就是为什么在源文件中使用这些字符时字节看起来不同的原因。见 Python 2 Unicode howto.