iva*_*eev 4 python character-encoding python-2.x python-3.x python-unicode
Python 何时、何地以及如何将编码隐式应用于字符串或进行隐式转码(转换)?
那些“默认”(即隐含)编码是什么?
例如,什么是编码:
字符串文字?
s = "Byte string with national characters"
us = u"Unicode string with national characters"
Run Code Online (Sandbox Code Playgroud)
类型转换为 Unicode 或从 Unicode 转换时的字节字符串?
data = unicode(random_byte_string)
Run Code Online (Sandbox Code Playgroud)
何时将字节和 Unicode 字符串写入文件或终端?
print(open("The full text of War and Peace.txt").read())
Run Code Online (Sandbox Code Playgroud)
这里涉及 Python 功能的多个部分:读取源代码并解析字符串文字、转码和打印。每个人都有自己的约定。
简短的回答:
str (Py2) -- 不适用,从文件中获取原始字节unicode(Py2)/ str(Py3) -- "源编码",默认为ascii(Py2) 和utf-8(Py3)bytes (Py3) -- none,文字中禁止使用非 ASCII 字符sys.getdefaultencoding()(ascii几乎总是)
UnicodeDecodeError/UnicodeEncodeErrorunicode(Py2) --<file>.encoding如果设置,否则sys.getdefaultencoding()str (Py2) -- 不适用,写入原始字节str(Py3) -- <file>.encoding,始终设置并默认为locale.getpreferredencoding()bytes(PY3) -没有,printING产生其repr()代替首先,一些术语的澄清,以便您正确理解其余部分。解码是从字节到字符(Unicode 或其他)的转换,而编码(作为一个过程)则相反。请参阅每个软件开发人员绝对、肯定地必须了解 Unicode 和字符集的绝对最小值(没有任何借口!)– Joel on Software以获得区别。
现在...
在源文件的开头,您可以指定文件的“源编码”(其确切效果将在后面描述)。如果未指定,则默认ascii为 Python 2 和utf-8Python 3。UTF-8 BOM 与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'
Run Code Online (Sandbox Code Playgroud)
因此,常规字符串将包含文件中的确切字节。而Unicode字符串将包含“源编码”解码文件的字节的结果。
如果解码失败,您将得到一个SyntaxError. 如果未指定编码时文件中存在非 ASCII 字符,则相同。最后,如果使用unicode_literalsfuture,则任何常规字符串文字(仅在该文件中)在解析时都被视为 Unicode 文字,这意味着什么。
Python 3 使用“源编码”将整个源文件解码为一系列 Unicode 字符。任何解析都在此之后完成。(特别是,这使得在标识符中包含 Unicode 成为可能。)由于所有字符串文字现在都是 Unicode,因此不需要额外的转码。在字节文字中,禁止使用非 ASCII 字符(必须使用转义序列指定此类字节),从而完全避免了该问题。
根据一开始的澄清:
str(Py2)/ bytes(Py3) -- bytes => 只能是decoded (直接,也就是;详情如下)unicode(Py2)/ str(Py3) --字符=> 只能是encoded在这两种情况下,如果未指定编码,sys.getdefaultencoding()则使用。它ascii (除非你取消注释代码块site.py,或做一些其他的黑客这是一个灾难)。因此,出于转码的目的,sys.getdefaultencoding()是“字符串的默认编码”。
现在,这里有一个警告:
adecode()和encode()- 使用默认编码 - 在转换时隐式完成str<->unicode:
UnicodeDecodeError/UnicodeEncodeError问题的三分之一是关于这个的)encode()astr或decode()a 时unicode(堆栈溢出问题的第二个三分之一)根本没有“默认编码”:现在禁止在str和之间进行隐式转换bytes。
bytes只能decoded和str- encoded,和encoding参数是强制性的。bytes->str(包括隐式)产生它的repr()代替(这仅对调试打印有用),完全避免编码问题str->bytes禁止转换这个问题与变量的值无关,但与你在print编辑时在屏幕上看到的内容有关——以及你是否会得到一个UnicodeEncodeErrorwhen printing。
unicodeis encoded with <file>.encodingif set; 否则,它被隐式转换str为如上所述。(UnicodeEncodeErrorSO 问题的最后三分之一属于这里。)
PYTHONIOENCODING环境变量覆盖。str的字节按原样发送到操作系统流。您将在屏幕上看到的具体字形取决于终端的编码设置(如果它是 UTF-8 之类的东西,如果您打印一个无效的 UTF-8 字节序列,您可能什么也看不到)。变化是:
files 打开文本与二进制mode本机接受stror bytes,相应地,并彻底拒绝处理错误的类型。文本模式文件总是有一个encoding集合,locale.getpreferredencoding(False)是默认的.print对于文本流仍然隐式地将所有内容转换为str,在按照上述bytes打印的情况下,repr()完全避免了编码问题| 归档时间: |
|
| 查看次数: |
6077 次 |
| 最近记录: |