Python 中的非 ASCII 字符问题
我该如何在Python源代码中成功添加非ASCII字符呢?
比如说:
a = "ű" - 这是匈牙利字母
--------Sample------
#-*- coding: iso8859_2 -*-
a = "ű"
print "ű"
---------------------
output = √
结果却不是我想要的ű。
4 个回答
你需要使用utf-8编码,而不是iso8859-2编码,像这样:
#-*- coding: utf-8 -*-
a = "ű"
print "ű"
输出结果:
ű
另外,确保你保存源代码文件时使用了正确的编码(这里是utf-8)。
其他回答提到要指定编码方式,并确保源文件是用这种编码保存的,这些都是对的。此外,如果你只用简单的引号,这种写法在Python 3中是可以的。如果你在用Python 2,就需要在前面加一个u
,这样它就变成了一个Unicode字符串:
a = u"ű"
print u"ű"
补充:也有可能你的控制台没有正确显示Unicode字符;我也遇到过这种情况。因为你的编辑器似乎能正常显示这些字符,所以可以试着把输出重定向到一个文件里,然后用你的编辑器打开这个文件。
看起来你是在美国的Windows控制台上使用Python。我这么说是因为你实际收到的字符是cp437编码的,而你打印的是iso8859_2编码的字符。不幸的是,cp437不支持ű
这个字符。如果你想看到这个字符,就不能使用美国的Windows控制台,建议使用Idle或Pythonwin。
你还应该使用Unicode字符串。当你使用coding: iso8859_2
时,你是在声明“这个源文件中的字符是用ISO 8859-2编码写入磁盘的。”如果你跟随那个链接,你会发现251这个值代表ű
。如果你把这个字节值写入cp437终端,你会看到一个平方根符号。使用Unicode字符串时,Python会把字节251转换成Unicode字符U+0171,这个字符唯一标识了带有双重重音的拉丁小写字母U。当打印到终端时,Python会尽量把Unicode字符转换成终端编码,如果不支持这个字符,就会报错,而不是输出一些乱码。
示例
# coding: iso8859_2
import unicodedata as ud
s = 'ű'
u = u'ű'
print 'ISO 8859-2 value:',ord(s)
print 'Unicode value: ',ord(u)
print 'Unicode name: ',ud.name(u)
print 'Unicode name of cp437 value %d: %s' % (ord(s),ud.name(s.decode('cp437')))
print s
print u
输出
ISO 8859-2 value: 251
Unicode value: U+0171
Unicode name: LATIN SMALL LETTER U WITH DOUBLE ACUTE
Unicode name of cp437 value 251: SQUARE ROOT
√
Traceback (most recent call last):
File "C:\ex.py", line 11, in <module>
print u
File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u0171' in position 0: character maps to <undefined>
所以你会看到字节字符串打印出了错误的平方根符号(√),而Unicode字符串正确地显示了这个字符不被支持。