Python在何时,何地以及如何将隐式编码应用于字符串,或者隐式转码(转换)?
那些“默认”(即隐含)编码是什么?
例如,编码是什么:
字符串文字?
s = "Byte string with national characters"
us = u”Unicode string with national characters”
类型转换为Unicode或从Unicode转换为字节字符串?
data = unicode(random_byte_string)
当从文件或终端写入字节和Unicode字符串时?
print(open("The full text of War and Peace.txt").read())
这里涉及Python功能的多个部分: 读取源代码并解析字符串文字 , 转码 和 打印 。每个都有自己的约定。
简短答案:
str
unicode
ascii
utf-8
bytes
sys.getdefaultencoding()
UnicodeDecodeError
UnicodeEncodeError
<file>.encoding
locale.getpreferredencoding()
print
repr()
首先,对一些术语进行澄清,以便您正确理解其余内容。 解码 是从 字节 到 字符(Unicode或其他)的转换 ,而 编码 (作为一个过程)则相反。请参阅绝对最低知识,每个软件开发人员绝对,肯定必须了解Unicode和字符集(无借口!)– Joel on Software以获得与众不同。
现在…
在源文件的开头,您可以指定文件的“源编码”(其确切效果将在后面说明)。如果未指定,则默认值为asciiPython 2和utf-8Python3。UTF-8BOM与utf-8编码声明具有相同的作用。
Python 2将源作为原始字节读取。看到Unicode文字时,它仅使用“源编码”来解析Unicode文字。(这比实际情况要复杂得多,但这是实际效果。)
> type t.py #encoding: cp1251 s = "абвгд" us = u"абвгд" print repr(s), repr(us) > py -2 t.py '\xe0\xe1\xe2\xe3\xe4' u'\u0430\u0431\u0432\u0433\u0434' <change encoding declaration in the file to cp866, do not change the contents> > py -2 t.py '\xe0\xe1\xe2\xe3\xe4' u'\u0440\u0441\u0442\u0443\u0444' <transcode the file to utf-8, update declaration or replace with BOM> > py -2 t.py '\xd0\xb0\xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4' u'\u0430\u0431\u0432\u0433\u0434'
因此, 常规字符串将包含文件中的确切字节。 而 Unicode字符串将包含“源编码”解码文件的字节的结果。
如果解码失败,您将得到一个SyntaxError。如果在未指定编码的情况下文件中包含非ASCII字符,则相同。最后,如果使用unicode_literalsfuture,那么解析时任何常规字符串文字(仅在该文件中)都将被视为Unicode文字,这意味着所有意义。
SyntaxError
unicode_literals
Python 3使用“源编码”将整个源文件解码为一系列Unicode字符。此后将进行任何解析。(特别是,这使得在标识符中包含Unicode成为可能。)由于所有字符串文字现在都是Unicode,因此不需要其他转码。在字节字面量中,禁止使用非ASCII字符(此类字节必须使用转义序列指定),从而完全避免了该问题。
根据开始时的说明:
decode
encode
在这两种情况下,如果未指定编码,sys.getdefaultencoding()则使用。它ascii (除非你取消注释代码块site.py,或做一些其他的黑客这是一个灾难)。因此, 出于代码转换的目的,sys.getdefaultencoding()是“字符串的默认编码”。
site.py
现在,有一个警告:
当转换时, adecode()和encode()-使用默认编码-隐式完成str<->unicode:
decode()
encode()
str<->unicode
根本没有“默认编码”:str和之间的隐式转换bytes现在被禁止。
encoding
bytes->str
str->bytes
这件事与变量的值无关,但与它被printed时在屏幕上看到的内容有关,以及与ingUnicodeEncodeError时是否会得到一个变量有关print。
PYTHONIOENCODING
更改为:
file
mode
locale.getpreferredencoding(False)