Windows 上 Python 默认编码实测:本机默认仍是 cp936

举报
yd_232353574 发表于 2026/11/09 07:46:32 2026/11/09
【摘要】 同一台 Windows 机器上做三组对照:默认和 PYTHONUTF8=0 时 open 的默认编码都是 cp936,这三组里只有设 1 才变 utf-8;该结果不适用于把「新版已默认 utf-8」当通用前提,并说明 sys.getdefaultencoding() 恒为 utf-8 与文件默认编码不是同一个量。

一条被反复转述、但这台机器上不成立的结论

搜 Windows 上 Python 中文乱码,常见说法是默认编码为 GBK(cp936),写文件不指定 encoding 就会踩坑。近两年又看到另一种说法:新版 Python 已经默认用 utf-8 了,不用再操心。两种说法互相矛盾,当场测一次就知道。我在这台 Windows 机器上把下面要用的四个值打印出来,结果与后一种说法对不上。

三组对照:默认、关掉、打开

import sys, locale, os, tempfile
p = os.path.join(tempfile.gettempdir(), "_enc_probe.txt")
f = open(p, "w")
print("utf8_mode:", sys.flags.utf8_mode)
print("open.encoding:", f.encoding)
f.close()
os.remove(p)
print("preferred:", locale.getpreferredencoding())
print("default:", sys.getdefaultencoding())

同一段代码,只改启动时的环境变量,结果分三种:

不设任何变量时,utf8_mode 是 0,open 的默认编码是 cp936,preferred 是 cp936,default 是 utf-8。

设 PYTHONUTF8=0 时,四项跟默认完全一样。因为这台机器本来就没开 UTF-8 模式,再关一次不会有任何变化。

设 PYTHONUTF8=1 时,四项变成 1、utf-8、utf-8、utf-8。

默认这一行才是重点:这台机器没开 UTF-8 模式,open 不写 encoding 拿到的就是 cp936。所以「新版已经默认 utf-8」这个说法不适用于本机;在这三组对照里,也只有显式设成 1 才让 open 的默认编码变过来。这不代表它是唯一途径,别的入口同样可能改写这个默认值,所以别把结论反过来当成「只要看版本号就知道编码」。

别把 default 当成 open 的默认值

四列里只有 default 从头到尾都是 utf-8,一次都没变。它和 open 的默认编码不是同一个量,也不决定 open 用哪个编码;把它当成 open 的默认编码,很容易得出「明明显示 utf-8,怎么文件还是 GBK」这种结论。

除了固定不变的 default,另外三列都跟着启动环境一起变。所以排查时该看的是这三列,而不是那一列从头到尾没动的 default。

于是同一个 open(p, "w") 在不同启动环境下写出的字节可能不同,读写两侧对编码的假设一旦错开,字节就对不上了。这也是「在我这儿好好的、到你那儿就乱码」的一种来源:代码里没有一行跟编码有关,行为却由启动环境决定。

把编码显式写出来

不管默认是什么,读写两侧都把编码写明:

with open("data.txt", "w", encoding="utf-8") as f:
    f.write("中文内容")
with open("data.txt", "r", encoding="utf-8") as f:
    print(f.read())

这样至少把「用哪个编码」这一维锁定了,不用去猜当前环境是哪一组。要注意显式写 encoding 并不等于把所有平台差异都消掉,换行翻译、路径编码这些仍然各自受环境影响,只是不会再因为默认编码猜错而读写不一致。

别用印象判断当前环境

遇到编码问题,先花十秒把上面四列打印出来,确认当前机器属于哪一组,再决定怎么改。默认编码是会被环境左右的值,靠记忆或搜索结果去猜,很容易在已经变过的环境上南辕北辙。乱码排查最怕拿一个没验证过的前提往下推,前提错了,后面每一步都白费力气。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。