有没有办法更改Python的open()默认文本编码?

17 投票
5 回答
26544 浏览
提问于 2025-04-18 14:20

我可以在不同平台上改变默认的 open() (io.open() 在 2.7 版本中) 文本编码吗?

这样我就不需要每次都写 open(...,encoding='utf-8') 了。

在文本模式下,如果没有指定 encoding,那么使用的编码会依赖于平台:会调用 locale.getpreferredencoding(False) 来获取当前的地区编码。

虽然文档没有说明如何 设置 首选编码。这个功能在 locale 模块里,所以我需要改变地区设置吗?有没有可靠的跨平台方法来设置 UTF-8 地区?这会影响到除了默认文本文件编码以外的其他东西吗?

或者说,改变地区设置是危险的(可能会导致问题),我应该使用像这样的自定义封装:

def uopen(*args, **kwargs):
    return open(*args, encoding='UTF-8', **kwargs)

5 个回答

-1

我建议不要更改locale,因为这可能会对你系统的其他部分产生很多意想不到的影响。open是一个系统级的函数调用,所以它的设置可能会影响到其他地方,至少会影响到使用同一个Python安装的其他Python程序。你的封装看起来很合适,结构也很简洁,便于移植,应该是正确的解决方案。

1

也许PEP 540(UTF-8模式)正是你需要的:

https://peps.python.org/pep-0540/

使用 -Xutf8

python.exe -Xutf8 -c "open('tmp.txt', 'w').write('天地玄黄0123'); print(open('tmp.txt').read())"

在PowerShell中使用 PYTHONUTF8

$env:PYTHONUTF8=1; python.exe -c "open('tmp.txt', 'w').write('天地玄黄0123'); print(open('tmp.txt').read())"

在命令提示符(Cmd)中使用 PYTHONUTF8

set PYTHONUTF8=1&& python.exe -c "open('tmp.txt', 'w').write('天地玄黄0123'); print(open('tmp.txt').read())"

在Bash中使用 PYTHONUTF8

PYTHONUTF8=1 python -c "open('tmp.txt', 'w').write('天地玄黄0123'); print(open('tmp.txt').read())"

你还可以执行 setx PYTHONUTF8 1 来将其保存为用户级别的环境变量。

1

如果你真的需要改变默认的编码方式,你可以替换掉内置的 open 函数。

original_open = __builtins__.open
def uopen(*args, **kwargs):
    if "b" not in (args[1] if len(args) >= 2 else kwargs.get("mode", "")):
        kwargs.setdefault("encoding", "UTF-8")
    return original_open(*args, **kwargs)
__builtins__.open = uopen

我在看到关于替换 print 的邮件后,写了并测试了这个代码片段,具体可以参考这封邮件

2

你可以设置编码……不过这样做有点 hacky(不太正规)。

import sys
sys.getdefaultencoding() #should print your default encoding
sys.setdefaultencoding("utf8") #error ... no setdefaultencoding ... but...
reload(sys)
sys.setdefaultencoding("utf8")  #now it succeeds ...

我建议你这样做:

main_script.py

import __builtin__
old_open = open
def uopen(*args, **kwargs):
    return open(*args, encoding='UTF-8', **kwargs)
__builtin__.open = uopen

这样你在任何地方调用 open 时,它都会使用 utf8 编码……不过如果你明确指定编码,可能会出现错误。

或者每次打开文件时都明确传递编码,或者使用你的封装方法……

Python 的一般原则是明确比隐含好,这意味着在打开文件时,正确的做法是明确声明你的编码……

20

不要随便改变地区设置或首选编码,因为:

  • 这可能会影响你代码的其他部分(或者你正在使用的库);
  • 这样会让人不清楚你的代码是依赖于open使用特定编码的。

相反,使用一个简单的包装函数:

from functools import partial
open_utf8 = partial(open, encoding='UTF-8')

如果需要的话,你还可以为所有关键字参数设置默认值。

撰写回答