【问题标题】:Is there a way to change Python's open() default text encoding?有没有办法改变 Python 的 open() 默认文本编码?
【发布时间】:2014-09-13 21:06:32
【问题描述】:

我可以跨平台更改默认的open() (io.open() in 2.7) 文本编码吗?

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

在文本模式下,如果未指定 encoding,则使用的编码取决于平台:调用 locale.getpreferredencoding(False) 以获取当前的语言环境编码。

虽然文档没有指定如何设置首选编码。该函数在locale 模块中,所以我需要更改语言环境?是否有任何可靠的跨平台方式来设置 UTF-8 语言环境?它会影响除默认文本文件编码以外的任何其他内容吗?

或者语言环境更改很危险(可能会破坏某些东西),我应该坚持使用自定义包装器,例如:

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

【问题讨论】:

    标签: python utf-8 character-encoding locale default


    【解决方案1】:

    我不会更改 locale 中的任何内容,因为它可能会对您系统的其他部分产生很多副作用。 open 是系统级函数调用,因此其设置可能会产生除此之外的影响,或者至少是使用相同 Python 安装的其他 Python 程序。您的包装器看起来很合适,非常干净和便携,并且看起来是正确的解决方案。

    【讨论】:

      【解决方案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 ...
      

      我会这样做

      ma​​in_script.py

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

      那么在您调用open 的任何地方,它都会使用utf8 编码...但是如果您明确添加编码,它可能会给您带来错误

      或在您打开文件时明确传递编码,或使用您的包装器...

      python 的一般哲学是显式优于隐式,这意味着“正确”的解决方案是在打开文件时显式声明您的编码...

      【讨论】:

      • 我不确定只覆盖builtins 中的函数是否安全,因为这也会修改已导入模块中的函数,并且某些库可能依赖于默认值。不过,在某些情况下它可能会派上用场。谢谢,+1
      【解决方案3】:

      不要更改语言环境或首选编码,因为;

      • 它可能会影响您代码的其他部分(或您正在使用的库);和
      • 不清楚您的代码是否依赖于使用特定编码的open

      改为使用简单的包装器:

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

      您还可以为所有关键字参数指定默认值(如果需要)。

      【讨论】:

      • 我试过 locale.setlocale() 并没有改变 Windows 上的默认编码。甚至是不同的非Unicode。所以我决定检查 CPython 的源代码,发现 getpreferredencoding uses GetACP WinAPI 函数,它“检索当前的 Windows ANSI 代码页标识符”。
      • Python 中没有机制可以覆盖此行为,除了使用 Joran 在另一个答案中建议的以及在this question 的答案中找到的与版本相关的黑客。根据我的阅读,在 Python 之外的 Windows 中也没有任何机制可以将此编码设置为 UTF-8。因此,鉴于如果不求助于黑客就无法设置此首选项,我同意更改此选项可能不可靠。已接受答案。
      【解决方案4】:

      如果确实需要更改默认编码,可以替换内置的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
      

      在我发现 this mails 关于替换邮件列表中的 print 后,我编写并测试了这个片段。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 2016-07-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多