当我从控制台运行我的应用程序时,我有很多"无法编码"和"无法解码"的Python问题.但是在Eclipse PyDev IDE中,默认字符编码设置为UTF-8,我很好.
我四处搜索设置默认编码,人们说Python sys.setdefaultencoding
在启动时删除了该功能,我们无法使用它.
那么什么是最好的解决方案呢?
这是一个更简单的方法(hack),它返回setdefaultencoding()
从sys
以下位置删除的函数:
import sys # sys.setdefaultencoding() does not exist, here! reload(sys) # Reload does the trick! sys.setdefaultencoding('UTF8')
但这不是一件安全的事情:这显然是一个黑客,因为在Python启动时sys.setdefaultencoding()
故意将其删除sys
.重新启用它并更改默认编码可能会破坏依赖于ASCII的默认代码(此代码可以是第三方,这通常会使修复它变得不可能或危险).
如果在尝试管道/重定向脚本输出时出现此错误
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
只需在控制台中导出PYTHONIOENCODING,然后运行您的代码.
export PYTHONIOENCODING=utf8
A)控制sys.getdefaultencoding()
输出:
python -c 'import sys; print(sys.getdefaultencoding())'
ascii
然后
echo "import sys; sys.setdefaultencoding('utf-16-be')" > sitecustomize.py
和
PYTHONPATH=".:$PYTHONPATH" python -c 'import sys; print(sys.getdefaultencoding())'
utf-16-be
你可以将你的sitecustomize.py放在更高的位置PYTHONPATH
.
您也可以尝试reload(sys).setdefaultencoding
@EOL
B)要控制stdin.encoding
并且stdout.encoding
您想要设置PYTHONIOENCODING
:
python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'
ascii ascii
然后
PYTHONIOENCODING="utf-16-be" python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'
utf-16-be utf-16-be
最后:您可以使用A)或B)或两者兼而有之!
从PyDev 3.4.1 开始,默认编码不再被更改.有关详细信息,请参阅此票
对于早期版本,解决方案是确保PyDev不以UTF-8作为默认编码运行.在Eclipse下,运行对话框设置("运行配置",如果我没记错的话); 您可以在常用选项卡上选择默认编码.如果您希望"早期"(换句话说:在PyDev环境中)出现这些错误,请将其更改为US-ASCII.另请参阅此解决方法的原始博客文章.
关于python2(仅限python2),前一些答案依赖于使用以下hack:
import sys reload(sys) # Reload is a hack sys.setdefaultencoding('UTF8')
不鼓励使用它(检查这个或这个)
在我的情况下,它带来了副作用:我正在使用ipython笔记本,一旦我运行代码,'print'功能就不再起作用了.我想它会有解决方案,但我认为使用黑客攻击不应该是正确的选择.
在尝试了很多选项之后,那个适合我的选项就是使用相同的代码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 notebooks和conda时,它就是 ~/anaconda2/lib/python2.7/sitecustomize.py
关于它的博客文章很有见地.
请参阅https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/.
我在下面解释它的内容.
在python 2中,对于字符串的编码没有强类型,你可以对不同编码的字符串执行操作,并且成功.例如,以下将返回True
.
u'Toshio' == 'Toshio'
这将适用于编码的每个(正常的,无前缀的)字符串,sys.getdefaultencoding()
默认为ascii
但不是其他字符串.
默认编码意味着在系统范围内更改site.py
,但不在其他地方更改.在用户模块中设置它的hacks(也在这里展示)只是:hacks,而不是解决方案.
Python 3确实将系统编码更改为默认为utf-8(当LC_CTYPE具有unicode感知时),但是基本问题是通过在与unicode字符串一起使用时显式编码"字节"字符串的要求来解决的.