在Python中处理Unicode和UTF-8字符以及编码时,我总是感到非常困惑。下面我将要详细说明的内容可能有一个简单的解释,但是,到目前为止,我还不能完全理解它。在
假设我有一个非常简单的.csv
文件,其中包含非ascii字符:
tildes.csv
:
Año,Valor
2001,Café
2002,León
我想用csv.DictReader对象读取该文件,并将其键/值存储为unicode
字符串,在python dict中正确地(未经转义)处理tilde和Django正确地处理unicode键/值集,所以我对自己说,是的,我也可以!!。。。但不是。。。看来我做不到
所以,我想:好吧,我从文件中读取了一个dict
(它的键是Año
和Valor
),这个文件将用转义字符加载到ascii中,但是我可以将它们编码成unicode值并将它们用作键。。。错了!在
这是我运行上述代码时看到的:
dct (original): {'A\xc3\xb1o': '2001', 'Valor': 'Caf\xc3\xa9'}
Año: 2001
Valor: Café
{u'A\xf1o': u'2001', u'Valor': u'Caf\xe9'}
dct (original): {'A\xc3\xb1o': '2002', 'Valor': 'Le\xc3\xb3n'}
Año: 2002
Valor: León
{u'A\xf1o': u'2002', u'Valor': u'Le\xf3n'}
所以第一行显示字典“原样”(转义)。很好,这里没什么奇怪的。然后我print
所有的键/值都解析为unicode。它显示了我想要的角色。太好了。但是,当我打印这些字符串时,我使用与重新编码字符串完全相同的指令,我尝试创建一个dict
(即utf_dct
变量),当我打印它时,我再次得到转义的值。在
编辑1:
实际上,我不认为我需要一个csv文件来表达我的意思。我刚在我的主机上试过:
>>> print "Año"
Año # Yeey!! There's hope!
>>> print {"Año": 2001}
{'A\xc3\xb1o': 2001} # 2 chars --> Ascii, I think I get this part
>>> print {u"Año": 2001}
{u'A\xf1o': 2001} # What happened here?
# Why am I seeing the 0x00F1 UTF-8 code
# from the Latin-1 Supplement (wiki:
# http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)
# instead of an ñ?
为什么我不能打印一个显示{u'Año': 2001}
的dict?我的终端显然接受了。这是怎么回事?在
当您打印字符串本身时,它将使用它的
str()
表示“很好地”打印出来。当您打印字典时,它的内容是使用它们的repr()
表示形式打印的,这种表示方式总是转义。字符串的内容在两种情况下都是相同的,只是Python显示它们的方式不同。第一种情况下,Año
周围没有引号,第二种情况下,引号围绕'A\xc3\xb1o'
打印,这是相同的原因。只是两种不同的显示格式。在下面是一个更简单的例子,可能有助于说明这种情况:
^{1}$有一个related bug report建议更改此行为,以便
repr
不会转义非ASCII字符。根据那个bug报告,这个更改是在Python3中进行的,所以您看到的工具可能使用的是Python3。在单个工具也可以显示任何他们喜欢的东西。工具不必只调用
str(someDict)
并显示结果;如果需要,它可以“手动”调用dict的内容str
,并从中构建自己的可显示版本。在相关问题 更多 >
编程相关推荐