更改Python的默认编码?
当我从控制台运行我的应用程序时,我有很多“无法编码”和“无法解码”的问题。但是在IDE中,默认字符编码设置为,我很好 我四处搜索设置默认编码,人们说Python在启动时删除了更改Python的默认编码?,python,encoding,utf-8,console,Python,Encoding,Utf 8,Console,当我从控制台运行我的应用程序时,我有很多“无法编码”和“无法解码”的问题。但是在IDE中,默认字符编码设置为,我很好 我四处搜索设置默认编码,人们说Python在启动时删除了sys.setdefaultencoding函数,我们无法使用它 那么最好的解决方案是什么呢?从3.4.1开始,默认编码不再被更改。 有关详细信息,请参阅 对于早期版本,解决方案是确保PyDev不会以UTF-8作为默认编码运行。在Eclipse下,运行对话框设置(“运行配置”,如果我没记错的话);您可以在“公用”选项卡上选择
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字符串和超出asciistr
的编码问题的最佳解决方案是:处理sys.stdout(类似文件的对象),该对象能够并可选地容忍需要:
- 如果由于某种原因,
为sys.stdout.encoding
,或不存在,或错误地为false或“小于”stdout终端或流的实际能力,则尝试提供正确的None
属性。最后,将sys.stdout&sys.stderr替换为一个类似于转换文件的对象encoding
- 当终端/流仍然无法对所有出现的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