Python是否同时使用ISO-8859-1与UTF-8编码?求解析相关现象
kh@lara:~/tmp $ python Python 3.9.2 (default, Mar 12 2021, 04:06:34) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> str = 'äöü' >>> len(str) 3 >>> ord(str[0]) 228 >>> ord(str[1]) 246 >>> ord(str[2]) 252 >>> ord(str[3]) Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: string index out of range >>> f = open ('uml.txt', 'w') >>> f.write(str) 3 >>> f.close() >>> kh@lara:~/tmp $ hexdump uml.txt 0000000 a4c3 b6c3 bcc3 0000006
问题与疑惑
有人能解释上述现象吗?228、246、252是ISO-8859-1编码中“äöü”对应的数值。
根据Python官方文档:ord(c)函数接收一个代表单个Unicode字符的字符串,返回该字符对应的Unicode码点整数。例如,ord('a')返回整数97,ord('€')(欧元符号)返回8364。该函数是chr()的逆操作。
疑惑点:Python是否同时在使用ISO-8859-1和UTF-8编码?
核心解释
这里并没有同时使用两种编码,本质是Unicode字符串与文件编码的区别,拆解如下:
- Python 3字符串是Unicode字符序列:
'äöü'在Python里是3个独立的Unicode字符,所以len(str)返回3,只能通过索引0、1、2访问,索引3自然越界报错。 ord()返回的是Unicode码点:Unicode的前256个码点完全兼容ISO-8859-1,所以ä的Unicode码点U+00E4十进制就是228,ö(U+00F6)是246,ü(U+00FC)是252——这不是Python在用ISO-8859-1,只是Unicode和该编码的数值刚好重合。- 文件写入用的是UTF-8编码:Python 3中
open()默认使用系统的首选编码(Linux下通常是UTF-8)。UTF-8中,这类Unicode码点(U+0080到U+07FF)会被编码为2个字节:ä→C3 A4ö→C3 B6ü→C3 BC
hexdump的输出是按双字节倒序显示的(比如a4c3实际是C3 A4),所以最终看到的6字节内容正好对应这三个字符的UTF-8编码结果。
内容的提问来源于stack exchange,提问作者art51go
相关产品推荐
相关产品推荐

