Python如何更改默认编码?

181

当我从控制台运行我的应用程序时,我经常遇到“无法编码”和“无法解码”的问题,涉及Python。但在Eclipse PyDev IDE中,字符编码默认设置为UTF-8,我没有问题。

我搜索了默认编码的设置,并且人们说Python在启动时删除了sys.setdefaultencoding函数,我们无法使用它。

那么有什么最佳解决方案呢?


1
请查看博客文章 *The Illusive setdefaultencoding*。 - djc
3
最好的解决方案是学会正确使用编码和解码,而不是使用hack方法。在Python2中做到这一点肯定是可以的,但需要牢记并始终使用自己的接口。我的经验表明,当你写的代码需要同时在Python2和Python3中工作时,这会变得非常棘手。 - Att Righ
14个回答

1
你可以更改整个操作系统的编码。在Ubuntu上,你可以这样做
sudo apt install locales 
sudo locale-gen en_US en_US.UTF-8    
sudo dpkg-reconfigure locales

0

如果你只想在文件读取/写入时获得稳定的UTF-8支持,而不需要在每个地方都进行相同的声明,这里有两个解决方案:

1. 在运行时修补io模块(自担风险的危险操作)

import pathlib as pathlib
import tempfile

import chardet


def patchIOWithUtf8Default():
    import builtins
    import importlib.util
    import sys
    spec = importlib.util.find_spec("io")
    module = importlib.util.module_from_spec(spec)
    exec(compile(spec.loader.get_source(spec.name) + """
    def open(*args, **kwargs):
        args = list(args)
        mode = kwargs.get('mode', (args + [''])[1])
        if (len(args) < 4 and 'b' not in mode) or 'encoding' in kwargs:
            kwargs['encoding'] = 'utf8'
        elif len(args) >= 4 and args[3] is None:
            args[3] = 'utf8'
        return _io.open(*args, **kwargs)
    """, module.__spec__.origin, "exec"), module.__dict__)
    sys.modules[module.__name__] = module
    builtins.open = __import__("io").open
    importlib.reload(importlib.import_module("pathlib"))


def main():
    patchIOWithUtf8Default()
    filename = tempfile.mktemp()
    text = "Common\n常\nSense\n识\n天地玄黄"
    print("Original text:", repr(text))
    pathlib.Path(filename).write_text(text)
    encoding = chardet.detect(open(filename, mode="rb").read())["encoding"]
    print("Written encoding by pathlib:", encoding)
    print("Written text by pathlib:", repr(open(filename, newline="", encoding=encoding).read()))


if __name__ == '__main__':
    main()

示例输出:

Original text: 'Common\n常\nSense\n识\n天地玄黄'
Written encoding by pathlib: utf-8
Written text by pathlib: 'Common\r\n常\r\nSense\r\n识\r\n天地玄黄'

2. 使用第三方库作为pathlib的包装器

https://github.com/baijifeilong/IceSpringPathLib

pip install IceSpringPathLib

import pathlib
import tempfile

import chardet

import IceSpringPathLib

tempfile.mktemp()
filename = tempfile.mktemp()
text = "Common\n常\nSense\n识\n天地玄黄"
print("Original text:", repr(text))

pathlib.Path(filename).write_text(text)
encoding = chardet.detect(open(filename, mode="rb").read())["encoding"]
print("\nWritten text by pathlib:", repr(open(filename, newline="", encoding=encoding).read()))
print("Written encoding by pathlib:", encoding)

IceSpringPathLib.Path(filename).write_text(text)
encoding = chardet.detect(open(filename, mode="rb").read())["encoding"]
print("\nWritten text by IceSpringPathLib:", repr(open(filename, newline="", encoding=encoding).read()))
print("Written encoding by IceSpringPathLib:", encoding)

示例输出:

Original text: 'Common\n常\nSense\n识\n天地玄黄'

Written text by pathlib: 'Common\r\n常\r\nSense\r\n识\r\n天地玄黄'
Written encoding by pathlib: GB2312

Written text by IceSpringPathLib: 'Common\n常\nSense\n识\n天地玄黄'
Written encoding by IceSpringPathLib: utf-8

0

将操作系统的默认编码设置为UTF-8。 例如,在Ubuntu上编辑文件/etc/default/locale并设置:

LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_ALL=en_US.UTF-8

-1

这个对我解决了问题。

import os
os.environ["PYTHONIOENCODING"] = "utf-8"

1
对我来说没有用。但是在进入Python之前,在shell中导出变量,或者使用reload(sys); sys.defaultencoding("utf-8")可以解决问题。 - Eric H.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接