【发布时间】:2015-10-06 19:31:54
【问题描述】:
我正在使用 Python 3(最近从 Python 2 切换)。我的代码通常在 Linux 上运行,但有时(不经常)在 Windows 上运行。根据open() 的Python 3 文档,如果未提供encoding 参数,则文本文件的默认编码来自locale.getpreferredencoding()。对于我的项目,我希望这个默认值是utf-8,无论它在什么操作系统上运行(目前,对于 Linux,它始终是 UTF-8,但对于 Windows 不是)。该项目有很多对open() 的调用,我不想将encoding='utf-8' 添加到所有这些调用中。因此,我想在 Windows 中更改语言环境的首选编码,就像 Python 3 所看到的那样。
我发现了一个以前的问题
“Changing the "locale preferred encoding"”,它有一个公认的答案,所以我认为我很高兴。但不幸的是,该答案中的建议命令及其第一条评论都不适用于 Windows。具体来说,接受的答案和它的第一条评论建议运行chcp 65001 和set PYTHONIOENCODING=UTF-8,我都试过了。请从我的 cmd 窗口查看以下脚本:
> py -i
Python 3.4.3 ...
>>> f = open('foo.txt', 'w')
>>> f.encoding
'cp1252'
>>> exit()
> chcp 65001
Active code page: 65001
> py -i
Python 3.4.3 ...
>>> f = open('foo.txt', 'w')
>>> f.encoding
'cp1252'
>>> exit()
> set PYTHONIOENCODING=UTF-8
> py -i
Python 3.4.3 ...
>>> f = open('foo.txt', 'w')
>>> f.encoding
'cp1252'
>>> exit()
请注意,即使在两个建议的命令之后,我打开的文件的编码仍然是cp1252,而不是预期的utf-8。
【问题讨论】:
-
也许这只是我的风格,但我更愿意编写一个包装器 open() 函数,您可以在其中指定编码。
-
不要使用
chcp 65001。 Windows 控制台不正确地支持 UTF-8,而且它也没有做你想做的事。locale.getpreferredencoding与控制台代码页无关;它基于 Windows 语言环境的 ANSI 编码。例如,如果您调用 Win32CreateFileA(ANSI) 而不是CreateFileW(UTF-16),则文件路径字符串将被解码为 ANSI 字符串(例如 Windows-1252)。 Windows 不允许将 UTF-8 用作 ANSI 字符集,C 运行时也不允许将 UTF-8 用于语言环境。 -
@eryksun 感谢您提供的信息,但它对我来说有太多特定于 Windows 的行话。我很少使用 Windows。我想要的只是一种对 Windows 8 或 Python 3 说的方式:“亲爱的 Windows 8 / Python 3,请注意,这台计算机上的所有文本文件都应该毫无例外地以 UTF-8 编码。请记住这个事实将来打开文本文件时。谢谢。”
-
@walrus,不存在这样的东西。 Windows 上的原生字符串格式是 UTF-16,使用 16 位
wchar_t字符串。 Windows API 仅支持旧版 ANSI API 的 8 位编码,遗憾的是它不允许 UTF-8。 Python 的首选编码只是调用GetACP来获取ANSI 代码页。我同情你并希望io.TextIOWrapper在所有平台上都默认为 UTF-8(你对 Linux 的假设也不总是有效的)。就目前情况而言,您需要一个包装函数,如前所述。 -
稍微努力一下就可以找到
TextIOWrapper源,并在其中看到_Py_device_encoding是使用Windows 控制台代码页(GetConsoleCP) 的,但仅适用于stdin、stdout 和stderr .否则它调用getpreferredencoding,它调用_getdefaultlocale,因此调用GetACP。
标签: python windows python-3.x encoding utf-8