努力理解 Python 输出(Unicode、UTF-8、不同的 Python 版本)
Struggling to understand Python Output (Unicode, UTF-8, different Python Versions)
环境设置
我正在使用默认编码 UTF-8 的 iTerm2。
1/ 混乱
启动 Python2.7 解释器,我不明白为什么我们看到看似相同功能的两个不同输出:
>>> print('你好')
你好
### vs
>>> '你好'
'\xe4\xbd\xa0\xe5\xa5\xbd'
我认为简单地按回车键会隐式调用 print()
函数 - 为什么我们观察到不同的输出?我在这里缺少哪些中间步骤?
2/ 混乱
另一方面,相同的代码在不同的 python 版本中会产生不同的输出:
Python2.7
>>> print('\xe4\xbd\xa0\xe5\xa5\xbd')
你好
Python3
>>> print('\xe4\xbd\xa0\xe5\xa5\xbd')
ä½ å¥½
有人可以解释为什么会这样吗?我猜想 Python2.7 将二进制文件按原样转发到标准输出,这可能是 UTF-8 相当于你好。那么 Python3 有什么不同之处呢?
我认为终端输出、shell 环境和字符串编码之间存在一些相互作用,我不太了解 python 版本不同。我理解 UTF-8、Unicode、ASCII,但无法将它们连接在一起。
谢谢!
print
输出对象的 str()
表示。如果交互式解释器中没有 print
,则输出对象的 repr()
表示。对于字符串,repr()
是一个调试输出,带有用于不可打印、非 ASCII 字符的转义码;而 str()
输出是“漂亮的”。
类 可以指定它们的 repr()
和 str()
格式。示例:
>>> class Test:
... def __repr__(self):
... return 'repr_of_Test'
... def __str__(self):
... return 'str_of_Test'
...
>>> t = Test()
>>> t
repr_of_Test
>>> print(t)
str_of_Test
Python 2.7 str
类型实际上等同于Python 3 bytes
类型。字节直接写入终端并以终端默认编码进行解释。请注意,字符串中的字节是 UTF-8,因为您的源文件是用 UTF-8 编写的,或者您的终端使用的是 UTF-8。在支持中文的 Windows 控制台上,您将获得在活动代码页中编码的字节:
C:\>chcp 936
Active code page: 936
C:\>py -2
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:22:17) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '你好'
'\xc4\xe3\xba\xc3'
Python 3 str
类型是Unicode字符串,然后在输出时以默认终端编码进行编码(注意,Python 3的更高版本在Windows将使用 Windows Unicode API 直接写入 Windows cmd.exe
终端,而不使用默认编码。
所以你的 Python 2.7 print
将 UTF-8 编码的字节直接发送到终端,在那里它们被解释为 UTF-8,而你的 Python 3 示例解释每个转义代码作为 Unicode 代码点。例如 '\xe4'
实际上是 Unicode U+00E4 ä
(带分音符的拉丁文小写字母 A),这正是打印的内容。为您的中文打印 Unicode 代码点,它将正常工作。
>>> print('\u4f60\u597d')
你好
与Python2相比,这比依赖于用户代码页才能正常工作的字节串更加一致。
环境设置
我正在使用默认编码 UTF-8 的 iTerm2。
1/ 混乱
启动 Python2.7 解释器,我不明白为什么我们看到看似相同功能的两个不同输出:
>>> print('你好')
你好
### vs
>>> '你好'
'\xe4\xbd\xa0\xe5\xa5\xbd'
我认为简单地按回车键会隐式调用 print()
函数 - 为什么我们观察到不同的输出?我在这里缺少哪些中间步骤?
2/ 混乱
另一方面,相同的代码在不同的 python 版本中会产生不同的输出:
Python2.7
>>> print('\xe4\xbd\xa0\xe5\xa5\xbd')
你好
Python3
>>> print('\xe4\xbd\xa0\xe5\xa5\xbd')
ä½ å¥½
有人可以解释为什么会这样吗?我猜想 Python2.7 将二进制文件按原样转发到标准输出,这可能是 UTF-8 相当于你好。那么 Python3 有什么不同之处呢?
我认为终端输出、shell 环境和字符串编码之间存在一些相互作用,我不太了解 python 版本不同。我理解 UTF-8、Unicode、ASCII,但无法将它们连接在一起。
谢谢!
print
输出对象的str()
表示。如果交互式解释器中没有print
,则输出对象的repr()
表示。对于字符串,repr()
是一个调试输出,带有用于不可打印、非 ASCII 字符的转义码;而str()
输出是“漂亮的”。类 可以指定它们的
repr()
和str()
格式。示例:>>> class Test: ... def __repr__(self): ... return 'repr_of_Test' ... def __str__(self): ... return 'str_of_Test' ... >>> t = Test() >>> t repr_of_Test >>> print(t) str_of_Test
Python 2.7
str
类型实际上等同于Python 3bytes
类型。字节直接写入终端并以终端默认编码进行解释。请注意,字符串中的字节是 UTF-8,因为您的源文件是用 UTF-8 编写的,或者您的终端使用的是 UTF-8。在支持中文的 Windows 控制台上,您将获得在活动代码页中编码的字节:C:\>chcp 936 Active code page: 936 C:\>py -2 Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:22:17) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> '你好' '\xc4\xe3\xba\xc3'
Python 3
str
类型是Unicode字符串,然后在输出时以默认终端编码进行编码(注意,Python 3的更高版本在Windows将使用 Windows Unicode API 直接写入 Windowscmd.exe
终端,而不使用默认编码。所以你的 Python 2.7
print
将 UTF-8 编码的字节直接发送到终端,在那里它们被解释为 UTF-8,而你的 Python 3 示例解释每个转义代码作为 Unicode 代码点。例如'\xe4'
实际上是 Unicode U+00E4ä
(带分音符的拉丁文小写字母 A),这正是打印的内容。为您的中文打印 Unicode 代码点,它将正常工作。>>> print('\u4f60\u597d') 你好
与Python2相比,这比依赖于用户代码页才能正常工作的字节串更加一致。