Python 3 utf-8编码似乎是错误的?

Python 3 utf-8编码似乎是错误的?,python,unicode,python-3.x,Python,Unicode,Python 3.x,我过去曾在Python 3.2中遇到过麻烦,但现在我在Python中遇到了一个关于utf-8编码的令人困惑的情况。 例如,假设我有一段代码: 'א'.encode() 结果是b'\xd7\x90'(或0xD790),但这是错误的:希伯来语字符Alef的utf-8编码应该是0x5D0 但是,使用utf-16作为编码返回正确的十六进制值,前缀为0xFFFE: 'א'.encode('utf-16') 这将返回b'\xff\xfe\xd0\x05' 我觉得我的理解中缺少了一些基本的东西, 所以用户

我过去曾在Python 3.2中遇到过麻烦,但现在我在Python中遇到了一个关于utf-8编码的令人困惑的情况。
例如,假设我有一段代码:

'א'.encode()
结果是
b'\xd7\x90'
(或
0xD790
),但这是错误的:希伯来语字符Alef的utf-8编码应该是
0x5D0

但是,使用utf-16作为编码返回正确的十六进制值,前缀为
0xFFFE

'א'.encode('utf-16')
这将返回
b'\xff\xfe\xd0\x05'

我觉得我的理解中缺少了一些基本的东西,

所以用户们,请帮助教育我

0x5d0
根本不是编码;它只是一个数字。是的,希伯来文字母ALEF是U+05D0,但UTF-8不是从代码点到字节的转录。相反,它在每个字节的MSB中使用特定的固定位集,并使用来自代码点值的可变位数填充LSB

0x5d0 = 101 1101 0000
      = 10111 010000
插入我们得到的:

二进制的或
101 1101 0000
。11位码点ABCDEFGHIJK的UTF-8编码

或者,在Python表示法中,
b'\xd7\x90'
否,
的unicode码点为0x5d0:

print("%x" % ord('א'))  
# '5d0'
当您将其编码为
utf-8
时,您可以得到一种表示特定代码点的可能方式
utf-16
将是表示它的另一种方式,它使用2个字节表示每个代码点。将it前缀加上
\xff\xfe
的原因是
encode('utf-16')
生成字节顺序标记(BOM)。如果明确指定字节顺序,则不会生成:

>>> a='א'
>>> a.encode('utf-16')
b'\xff\xfe\xd0\x05'
>>> a.encode('utf-16-le')
b'\xd0\x05'
>>> a.encode('utf-16-be')
b'\x05\xd0'

这是该代码点的正确UTF-8编码,请看,因为您混淆了非常基本的Unicode术语(代码点和编码),您迫切需要阅读啊,Windows将UTF-16LE误导性地描述为“Unicode”的另一个受害者…re:将代码点转录为字节:这有点像(特别是如果你用编码代替转录的话)。我认为这不是一个简单的转录(那将是UCS-4)。
print("%x" % ord('א'))  
# '5d0'
>>> a='א'
>>> a.encode('utf-16')
b'\xff\xfe\xd0\x05'
>>> a.encode('utf-16-le')
b'\xd0\x05'
>>> a.encode('utf-16-be')
b'\x05\xd0'