use*_*696 0 python unicode encoding utf-8 latin1
对于 PYTHON 2.7(我在 3 中使用了编码,现在很困惑......希望得到一些如何在 python 3 中复制此测试的建议......)
\n\n对于欧元字符 (\xe2\x82\xac),我使用此工具查找了其 utf8 十六进制代码点。它说是0x20AC。
\n\n对于 Latin1(再次使用 Python2 2.7),我使用解码来获取其十六进制代码点:
\n\n>>import unicodedata\n>>p=\'\xe2\x82\xac\'\n## notably x80 seems to correspond to [Windows CP1252 according to the link][2]\n>>p.decode(\'latin-1\') \n>>u\'\\x80\'\n
Run Code Online (Sandbox Code Playgroud)\n\n然后我对它们都使用了这个 print 语句,这就是我得到的:
\n\n对于 utf8:
\n\n>>> print unichr(0x20AC).encode(\'utf-8\')\n\xc3\xa2\xe2\x80\x9a\xc2\xac\n
Run Code Online (Sandbox Code Playgroud)\n\n对于拉丁-1:
\n\n>>> print unichr(0x80).encode(\'latin-1\')\n\xe2\x82\xac\n
Run Code Online (Sandbox Code Playgroud)\n\n到底发生了什么?为什么编码对于 utf-8 返回 \'\xc3\xa2\xe2\x80\x9a\xc2\xac\' ?另外...看来Latin1 十六进制代码点可能与它们的utf8 对应代码点不同(我有一位同事认为不同——说Latin1 在这方面就像ASCII)。但不同代码点的存在似乎对我来说另有暗示...然而,python 2.7 读取Windows CP1252 \'x80\'的原因对我来说是一个真正的谜......这是 latin-1 的标准在Python 2.7?
\n你在这里有一些严重的误解。如果您还没有阅读Python 2和Python 3的 Unicode HOWTO ,您应该从那里开始。
\n\n首先,UTF-8是Unicode到8位字节的编码。不存在 UTF-8 代码点这样的东西0x20AC
。有一个Unicode代码点 U+20AC,但在 UTF-8 中,它是三个字节:0xE2
, 0x82
, 0xAC
。
这解释了你的困惑:
\n\n\n\n\n为什么编码对于 utf-8 返回 \'\xc3\xa2\xe2\x80\x9a\xc2\xac\' ?
\n
事实并非如此。它返回字节字符串\'\\xE2\\x82\\xAC\'
。然后您print
将其输出到控制台。您的控制台可能是 CP-1252,因此它会将这些字节解释为 CP-1252,从而为您提供\xc3\xa2\xe2\x80\x9a\xc2\xac
.
同时,当你写下这个:
\n\np=\'\xe2\x82\xac\'\n
Run Code Online (Sandbox Code Playgroud)\n\n控制台不提供 Python Unicode,而是提供 CP-1252 中的 Python 字节,Python 仅将其存储为字节。欧元符号的 CP-1252 是\\x80
。因此,这与输入相同:
p=\'\\x80\'\n
Run Code Online (Sandbox Code Playgroud)\n\n但在Latin-1中,\\x80
不是欧元符号,而是一个不可见的控制字符,相当于Unicode U+0080。所以,当你打电话时p.decode(\'latin-1\')
,你就会回来u\'\\x80\'
。这正是您所看到的。
无法在 Python 3 中重现这一点的原因是,在 Python 3 中,str
和纯字符串文字是 Unicode 字符串,而不是字节字符串。所以,当你写这个时:
p=\'\xe2\x82\xac\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\xe2\x80\xa6 控制台向 Python 提供一些字节,然后 Python 使用它为控制台猜测的字符集 (CP-1252) 自动将这些字节解码为 Unicode。所以,它相当于这样写:
\n\np=\'\\u20ac\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\xe2\x80\xa6 或这个:
\n\np=b\'\\x80\'.decode(sys.stdin.encoding)\n
Run Code Online (Sandbox Code Playgroud)\n\n另外,您一直说“十六进制代码点”来表示各种不同的事物,但这些都没有任何意义。
\n\n代码点是一个 Unicode 概念。Python 中的字符串unicode
是代码点的序列。A是字节str
序列,而不是代码点。十六进制只是数字的一种表示方式\xe2\x80\x94,十六进制数,或,与十进制数是一样的,十六进制数与十进制数是一样的。20AC
0x20AC
8364
0x80
128
该字节序列本身作为文本没有任何固有含义;它需要与编码结合起来才有意义。根据编码的不同,某些代码点可能根本无法表示,而其他代码点可能需要 2 个或更多字节来表示。
\n\n最后:
\n\n\n\n\n另外...看来Latin1 十六进制代码点可能与它们的utf8 对应代码点不同(我有一位同事认为不同——说Latin1 在这方面就像ASCII)。
\n
Latin-1 是 ASCII 的超集。Unicode 也是 Latin-1 可打印子集的超集;部分直到 U+FF 的 Unicode 字符(以及直到 U+7F 的所有可打印字符)都以 UTF-8 编码为与代码点具有相同值的字节,但不是全部。CP-1252 是Latin-1 可打印子集的不同超集。由于ASCII 或 Latin-1 中都没有欧元符号,因此 CP-1252 和 UTF-8 以不同的方式表示它是完全合理的。
\n 归档时间: |
|
查看次数: |
2720 次 |
最近记录: |