显然,我可以在Python 2.7中做到这一点:
value = '國華'
似乎Python正在使用编码将字符串文字中的字符编码为字节字符串。什么是编码?这是sys.getdefaultencoding()
中定义的编码,源文件的编码还是其他什么?
由于
答案 0 :(得分:7)
getdefaultencoding
与源文件或终端的编码无关。它是用于将字节字符串隐式转换为Unicode字符串的编码,并且在Python 2.X(Python 3.X上的'utf8')上应始终为'ascii'。
在Python 2.X上,未声明编码的脚本中的代码行会产生错误:
SyntaxError: Non-ASCII character '\x87' in file ...
实际的非ASCII字符可能会有所不同,但如果没有编码声明,它将无法使用。编码声明 required 在Python 2.X上使用非ASCII字符。编码声明必须与源文件编码匹配。例如:
# coding: utf8
value = '國華'
保存为cp936时产生:
SyntaxError: 'utf8' codec can't decode byte 0x87 in position 9: invalid start byte
当编码正确时,字节字符串中的字节实际上是源文件中的字节,因此它将包含字符的编码字节。当Python解析Unicode字符串时,使用声明的源编码将字节解码为Unicode。请注意在cp936控制台上打印UTF-8字节字符串和Unicode字符串时的区别:
# coding: utf8
value = '國華'
print value,repr(value)
value = u'國華'
print value,repr(value)
输出:
鍦嬭彲 '\xe5\x9c\x8b\xe8\x8f\xaf'
國華 u'\u570b\u83ef'
字节字符串包含两个字符的3字节UTF-8编码,但显示不正确,因为cp936终端无法理解字节序列。 Unicode打印正确,字符串包含从源文件的UTF-8字节解码的Unicode代码点。
注意声明和使用与终端匹配的编码时的区别:
# coding: cp936
value = '國華'
print value,repr(value)
value = u'國華'
print value,repr(value)
输出:
國華 '\x87\xf8\xc8A'
國華 u'\u570b\u83ef'
字节字符串的内容现在是两个字符的2字节cp936编码('A'相当于'\ x41'),并且由于终端理解cp936字节序列而正确显示。 Unicode字符串包含与前一个示例相同的两个字符的Unicode代码点,因为源字节序列使用声明的源编码解码为Unicode。
如果脚本具有正确的源编码声明并使用Unicode字符串作为文本,则无论终端编码 2 ,它都将显示正确的字符 1 。如果终端不支持该字符而不是显示错误的字符,它将抛出UnicodeEncodeError
。
最后一点:Python 2.X默认为'ascii'编码,除非另有声明,如果编码支持,则允许字节字符串中使用非ASCII字符。 Python 3.X默认为'utf8'编码(因此请确保以该编码保存或以其他方式声明),并且不允许字节字符串中的非ASCII字符。
1 如果终端字体支持该字符 2 如果终端编码支持该字符。
答案 1 :(得分:0)
value = b'國華'
没有意义(Python {2.x中隐含b
) - 为什么你想要一个包含字符的字节字符串? Python只是在终端/编辑器使用的任何编码中重现字节。你想要的是一个字符字符串:
value = u'國華'
在源代码文件(而不是交互式shell)中,不要忘记declare the encoding,方法是在文件开头添加以下行:
# -*- coding: utf-8 -*-