Python使用open函数读写文件时是否始终采用UTF-8编码?
问题解答
1. 读文件的断言代码是否可能失败?
是的,肯定会失败,当操作系统默认编码不是UTF-8的时候。
open()在文本模式下的默认编码由系统决定:
- Linux/macOS通常默认UTF-8,这时候读取C2 A5字节会正确解码为
¥,断言通过。 - Windows默认编码多为cp1252或gbk:
- 用cp1252解码C2 A5会得到
Â¥(cp1252中0xC2是Â,0xA5是¥),断言失败。 - 用gbk解码C2 A5会直接抛出解码错误(因为C2 A5不是合法的gbk字节序列),导致脚本崩溃,断言自然不通过。
- 用cp1252解码C2 A5会得到
2. 写文件的代码是否可能生成不含C2 A5的文件?
是的,完全可能。
同样取决于open()的默认编码:
- 如果系统默认编码是cp1252,
'¥'会被编码为b'\xa5',文件中只有0xA5字节,没有C2 A5。 - 如果系统默认编码是cp437,
'¥'会被编码为b'\x9d',文件字节是0x9d,也不是C2 A5。
只有当系统默认编码是UTF-8时,写入的才是C2 A5字节。
3. 为什么加了# coding: cp437还是生成C2 A5?
# coding: cp437的作用是告诉Python解析脚本文件本身的编码,也就是用来解码脚本里的字符串字面量'¥',让Python能正确识别这个字符为Unicode的¥。但它和open()读写文件时用的编码完全无关。
open()在不指定encoding参数时,依然用系统默认编码。如果你的系统默认是UTF-8,那写入时还是会把Unicode的¥编码成UTF-8的C2 A5。要让写入用cp437,必须给open()指定encoding参数:
with open('yen.txt', 'w', encoding='cp437') as f: f.write('¥')
这样才会生成0x9d字节的文件。
4. 上传GitHub后日元符号消失的原因?
GitHub默认以UTF-8编码解析并显示文本文件。问题出在你的脚本文件本身的编码和GitHub的解析不匹配:
- 如果你用
# coding: cp437声明了脚本编码,但实际保存脚本时用的不是cp437编码,或者保存时¥符号被转换成了其他字节,GitHub用UTF-8解码这些字节时就会出现乱码,甚至无法识别为有效字符,导致符号消失。 - 另外,Python 3默认脚本编码就是UTF-8,除非你有特殊需求,没必要指定非UTF-8的脚本编码。建议将脚本文件保存为UTF-8编码,这样上传到GitHub后就能正常显示
¥符号。
内容的提问来源于stack exchange,提问作者Watchduck
相关产品推荐
相关产品推荐

