python - Python默认字符串编码

标签 python python-3.x character-encoding python-2.x python-unicode

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(Py2)-不适用,从文件中获取原始字节
unicode(Py2)/ str(Py3)-“源编码”,默认值为ascii(Py2)和utf-8(Py3)
bytes(Py3)-无,文字中禁止使用非ASCII字符

为了进行转码:


both(Py2)-sys.getdefaultencoding()ascii几乎总是)


有些隐式转换通常会导致UnicodeDecodeError / UnicodeEncodeError

both(Py3)-无,在转换时必须明确指定编码

出于I / O的目的:


unicode(Py2)-<file>.encoding如果已设置,否则sys.getdefaultencoding()
str(Py2)-不适用,写入原始字节
str(Py3)-<file>.encoding,始终设置且默认为locale.getpreferredencoding()
bytes(Py3)-无,print ing生成其repr()





首先,对一些术语进行澄清,以便您正确理解其余内容。解码是从字节到字符(Unicode或其他)的转换,而编码(作为一个过程)则相反。请参见The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) – Joel on Software以获取区别。

现在...

读取源代码并解析字符串文字

At the start of a source file, you can specify the file's "source encoding"(稍后将描述其确切的效果)。如果未指定,则Python 2的默认值为ascii,Python 3的默认值为utf-8。UTF-8BOM的作用与utf-8编码声明相同。

Python 2

Python 2将源作为原始字节读取。看到Unicode文字时,它仅使用“源编码”来解析Unicode文字。 (It's more complicated than that under the hood但这是实际效果。)

> 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_literals future,则在解析时将任何常规字符串文字(in that file only)视为Unicode文字,这意味着所有含义。

Python 3

Python 3使用“源编码”将整个源文件解码为Unicode字符序列。此后将进行任何解析。 (特别是,这使得在标识符中包含Unicode成为可能。)由于所有字符串文字现在都是Unicode,因此不需要其他转码。在字节文字中,禁止使用非ASCII字符(此类字节必须使用转义序列指定),从而完全避免了该问题。

转码

根据开始时的说明:


str-字节=>只能被decode d(直接,即;详细信息如下)
unicode-字符=>只能是encode d


Python 2

在这两种情况下,如果未指定编码,则使用sys.getdefaultencoding()。它是ascii(除非您取消注释site.pyor do some other hacks中的are a recipe for disaster中的代码块)。因此,出于代码转换的目的,sys.getdefaultencoding()是“字符串的默认编码”。

现在,有一个警告:


在转换decode()时隐式完成了encode()str<->unicode的默认编码:


以字符串格式(关于SO的UnicodeDecodeError / UnicodeEncodeError问题的三分之一与此有关)
尝试encode()一个strdecode()一个unicode时(SO问题的第二三分之一)



Python 3

根本没有“默认编码”:现在禁止在strbytes之间进行隐式转换。
(随着来自困惑用户的大量SO问题的证明,事实证明,这带来的麻烦多于其价值。)


bytes只能是decode d和str-encode d,并且encoding参数是必需的。
转换bytes->str(隐式包含)会生成其repr()(仅对打印有用),从而完全避免了编码问题
禁止转换str->bytes


列印

This matter与变量的值无关,但与变量print时在屏幕上看到的内容有关–以及UnicodeEncodeError时是否会得到print

Python 2


如果设置了unicode,则将encode设置为<file>.encoding。否则,将其隐式转换为str。 (UnicodeEncodeError SO问题的最后三分之一属于此处。)


对于标准流,在启动时会从各种特定于环境的来源中猜测流的编码,并且可以使用PYTHONIOENCODING envvar覆盖流的编码。

str的字节按原样发送到OS流。您将在屏幕上看到哪些特定字符取决于终端的编码(如果它类似于UTF-8,则如果打印无效的UTF-8字节序列,您可能什么也看不到)。


Python 3

更改为:


现在,使用文本与二进制file开头的mode本身对应地接受strbytes,并且完全拒绝处理错误的类型。文本模式文件始终设置为encoding,即locale.getpreferredencoding(False) being the default
文本流的print仍将所有内容隐式转换为str,在bytes的情况下,按照上述方法打印其repr(),从而完全避免了编码问题

关于python - Python默认字符串编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49991870/

相关文章:

python - 我可以使用 Node.js 作为后端并使用 Python 来进行 AI 计算吗?

python - pysimplegui 无按钮文本更新

php - 使用 PHP 插入 MySQL 数据库时出现土耳其字符问题

mysql - 如何在一个实例中为数据库的多个字符集配置 my.cnf

python - 如何使两个同名音频的长度相等?

python - 给定用户名列表,使用 Pymongo 立即更新所有用户名

python - 将变量注入(inject)导入命名空间

java - HTML特殊字符解码

python - 如何将特定月份值与 pandas 数据框中的日期相加?

python-3.x - 如何在 Tensorflow 中输出预测?