更改Python的默认编码?

更改Python的默认编码?,python,encoding,utf-8,console,Python,Encoding,Utf 8,Console,当我从控制台运行我的应用程序时,我有很多“无法编码”和“无法解码”的问题。但是在IDE中,默认字符编码设置为,我很好 我四处搜索设置默认编码,人们说Python在启动时删除了sys.setdefaultencoding函数,我们无法使用它 那么最好的解决方案是什么呢?从3.4.1开始,默认编码不再被更改。 有关详细信息,请参阅 对于早期版本,解决方案是确保PyDev不会以UTF-8作为默认编码运行。在Eclipse下,运行对话框设置(“运行配置”,如果我没记错的话);您可以在“公用”选项卡上选择

当我从控制台运行我的应用程序时,我有很多“无法编码”和“无法解码”的问题。但是在IDE中,默认字符编码设置为,我很好

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

那么最好的解决方案是什么呢?

从3.4.1开始,默认编码不再被更改。 有关详细信息,请参阅

对于早期版本,解决方案是确保PyDev不会以UTF-8作为默认编码运行。在Eclipse下,运行对话框设置(“运行配置”,如果我没记错的话);您可以在“公用”选项卡上选择默认编码。如果您希望“尽早”出现这些错误(换句话说:在您的PyDev环境中),请将其更改为US-ASCII。另请参见。

A)控制
sys.getdefaultencoding()
输出:

python -c 'import sys; print(sys.getdefaultencoding())'
python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'
ascii

然后

utf-16-be

您可以将您的站点customize.py放在
PYTHONPATH
的更高位置

你也可以试试@EOL

B)控制
stdin.encoding
stdout.encoding
要设置
PYTHONIOENCODING

python -c 'import sys; print(sys.getdefaultencoding())'
python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'
ascii

然后

utf-16-be utf-16-be

最后:您可以使用A)B)两者

这里有一个更简单的方法(hack),它将从
sys
中删除的
setdefaultencoding()
函数返回给您:

import sys
# sys.setdefaultencoding() does not exist, here!
reload(sys)  # Reload does the trick!
sys.setdefaultencoding('UTF8')
...
def set_defaultencoding_globally(encoding='utf-8'):
    assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
    import imp
    _sys_org = imp.load_dynamic('_sys_org', 'sys')
    _sys_org.setdefaultencoding(encoding)

if __name__ == '__main__':
    sys.stdout = sys.stderr = SmartStdout()
    set_defaultencoding_globally('utf-8') 
    s = 'aouäöüфżß²'
    print s
(注意:对于Python 3.4+:
reload()
位于
importlib
库中。)


这不是一件安全的事情,但是:这显然是一种黑客行为,因为当Python启动时,
sys.setdefaultencoding()
被故意从
sys
中删除。重新启用并更改默认编码(此代码可能是第三方代码,这通常会使修复变得不可能或危险)。

如果在尝试管道/重定向脚本输出时出现此错误

UnicodeEncodeError:“ascii”编解码器无法对位置0-5的字符进行编码:序号不在范围(128)

只需在控制台中导出Python编码,然后运行代码


导出pythonionecoding=utf8

有一篇关于它的有见地的博客文章

我将其内容解释如下

在Python2中,对于字符串的编码没有那么强的类型化,您可以对不同编码的字符串执行操作,并且成功。例如,以下内容将返回
True

u'Toshio' == 'Toshio'
这将适用于在
sys.getdefaultencoding()
中编码的每个(正常的、不固定的)字符串,该字符串默认为
ascii
,而其他字符串则不适用

默认编码是要在
site.py
中在系统范围内更改的,但不能在其他地方更改。在用户模块中设置它的黑客(这里也有介绍)只是:黑客,而不是解决方案

Python 3确实将系统编码更改为默认utf-8(当LC_CTYPE支持unicode时),但基本问题得到了解决,只要与unicode字符串一起使用,就需要显式编码“字节”字符串。

关于python2(仅限于python2),以前的一些答案依赖于使用以下破解:

import sys
reload(sys)  # Reload is a hack
sys.setdefaultencoding('UTF8')
不鼓励使用它(检查或)

在我的例子中,它带来了一个副作用:我正在使用ipython笔记本电脑,一旦我运行代码,“打印”功能就不再工作了。我想会有解决办法,但我仍然认为使用黑客不应该是正确的选择

在尝试了许多选项之后,对我有效的一个选项是在
sitecustomize.py
中使用相同的代码,而这段代码的本意是
。评估该模块后,将从sys中删除setdefaultencoding函数

因此,解决方案是在文件
/usr/lib/python2.7/sitecustomize.py
中附加以下代码:

import sys
sys.setdefaultencoding('UTF8')
当我使用virtualenvwrapper时,我编辑的文件是
~/.virtualenvs/venv name/lib/python2.7/sitecustomize.py

当我使用python笔记本和conda时,它是
~/anaconda2/lib/python2.7/sitecustomize.py

首先:
重新加载(sys)
,仅仅根据输出终端流的需要设置一些随机默认编码是不好的做法<代码>重新加载通常会根据环境更改sys中已放置的内容,例如sys.stdin/stdout streams、sys.excepthook等

stdout上编码问题的解决 我所知道的解决sys.stdout上打印unicode字符串和超出ascii
str
的编码问题的最佳解决方案是:处理sys.stdout(类似文件的对象),该对象能够并可选地容忍需要:

  • 如果由于某种原因,
    sys.stdout.encoding
    None
    ,或不存在,或错误地为false或“小于”stdout终端或流的实际能力,则尝试提供正确的
    encoding
    属性。最后,将sys.stdout&sys.stderr替换为一个类似于转换文件的对象

  • 当终端/流仍然无法对所有出现的unicode字符进行编码,并且您不想因此而中断
    打印
    ,您可以在类似于转换文件的对象中引入encode with replace行为

这里有一个例子:

#!/usr/bin/env python
# encoding: utf-8
import sys

class SmartStdout:
    def __init__(self, encoding=None, org_stdout=None):
        if org_stdout is None:
            org_stdout = getattr(sys.stdout, 'org_stdout', sys.stdout)
        self.org_stdout = org_stdout
        self.encoding = encoding or \
                        getattr(org_stdout, 'encoding', None) or 'utf-8'
    def write(self, s):
        self.org_stdout.write(s.encode(self.encoding, 'backslashreplace'))
    def __getattr__(self, name):
        return getattr(self.org_stdout, name)

if __name__ == '__main__':
    if sys.stdout.isatty():
        sys.stdout = sys.stderr = SmartStdout()

    us = u'aouäöüфżß²'
    print us
    sys.stdout.flush()
在Python 2/2+3代码中使用beyond ascii纯字符串文字 我认为更改全局默认编码(仅限UTF-8)的唯一好理由是关于应用程序源代码的决定,而不是因为I/O流编码问题:对于编写
...
def set_defaultencoding_globally(encoding='utf-8'):
    assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
    import imp
    _sys_org = imp.load_dynamic('_sys_org', 'sys')
    _sys_org.setdefaultencoding(encoding)

if __name__ == '__main__':
    sys.stdout = sys.stderr = SmartStdout()
    set_defaultencoding_globally('utf-8') 
    s = 'aouäöüфżß²'
    print s
sys.stdout = io.open(sys.stdout.fileno(), 'w', encoding='utf8')
# Encoding for file names
filesystemencoding = sys.getfilesystemencoding()

encoding = "ascii"
if sys.platform == 'win32':
    # On Windows, we could use "mbcs". However, to give the user
    # a portable encoding name, we need to find the code page 
    try:
        # --> 6/5/17 hack to force IDLE to display utf-8 rather than cp1252
        # --> encoding = locale.getdefaultlocale()[1]
        encoding = 'utf-8'
        codecs.lookup(encoding)
    except LookupError:
        pass
import os
os.environ["PYTHONIOENCODING"] = "utf-8"
sudo apt install locales 
sudo locale-gen en_US en_US.UTF-8    
sudo dpkg-reconfigure locales
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_ALL=en_US.UTF-8