具有非ascii字符的字节字符串文字

时间:2012-08-16 18:30:32

标签: python unicode encoding internationalization

显然,我可以在Python 2.7中做到这一点:

value = '國華'

似乎Python正在使用编码将字符串文字中的字符编码为字节字符串。什么是编码?这是sys.getdefaultencoding()中定义的编码,源文件的编码还是其他什么?

由于

2 个答案:

答案 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 -*-
相关问题