为什么我们不应该在py脚本中使用sys.setdefaultencoding(“utf-8”)?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

我已经在脚本的顶部看到了几个使用它的py脚本。在什么情况下应该使用它?

import sys
reload(sys)
sys.setdefaultencoding("utf-8")
提问于
用户回答回答于

根据文档:这允许您从默认的ASCII切换到其他编码,例如UTF-8,Python运行时只要将字符串缓冲区解码为unicode就会使用它。

此功能仅在Python启动时可用,此时Python会扫描环境。它必须在全系统模块中调用sitecustomize.py,在评估完该模块后,该setdefaultencoding()功能将从sys模块中删除。

实际使用它的唯一方法是使用重新加载hack来恢复属性。

另外,它的使用sys.setdefaultencoding()一直令人沮丧,并且它已经成为py3k中的一个无用的工具。py3k的编码被硬连线到“utf-8”并且改变它会产生一个错误。

我建议读一些指针:

用户回答回答于

解决方案:

9/10倍可以通过对编码/解码的正确理解来解决。

1/10人有不正确定义的区域设置或环境,需要设置:

PYTHONIOENCODING="UTF-8"  

在他们的环境中修复控制台打印问题。

它有什么作用?

sys.setdefaultencoding("utf-8")(避免重复使用)改变了Python 2.x需要将Unicode()转换为str()(反之亦然)并且未给出编码时使用的默认编码/解码。即:

str(u"\u20AC")
unicode("€")
"{}".format(u"\u20AC") 

在Python 2.x中,默认编码设置为ASCII,并且上述示例将失败:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

(我的控制台被配置为UTF-8,所以"€" = '\xe2\x82\xac',因此例外\xe2

要么

UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)

sys.setdefaultencoding("utf-8")将允许这些为工作,但不一定适用于不使用UTF-8的人。ASCII的缺省值确保编码假设不会被编入代码

安慰

sys.setdefaultencoding("utf-8")也出现了修复的副作用sys.stdout.encoding,用于在控制台上打印字符时使用。Python使用用户的区域设置(Linux / OS X / Un * x)或代码页(Windows)来设置它。偶尔,用户的区域设置被破坏,只需要PYTHONIOENCODING修复控制台编码

例:

$ export LANG=en_GB.gibberish
$ python
>>> import sys
>>> sys.stdout.encoding
'ANSI_X3.4-1968'
>>> print u"\u20AC"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
>>> exit()

$ PYTHONIOENCODING=UTF-8 python
>>> import sys
>>> sys.stdout.encoding
'UTF-8'
>>> print u"\u20AC"
€

sys.setdefaultencoding(“utf-8”)有什么不好?

在理解默认编码为ASCII的情况下,人们已经开发了16年的Python 2.x版本。UnicodeError编写了异常处理方法来处理发现包含非ASCII字符串的字符串到Unicode转换。

https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/

def welcome_message(byte_string):
    try:
        return u"%s runs your business" % byte_string
    except UnicodeError:
        return u"%s runs your business" % unicode(byte_string,
            encoding=detect_encoding(byte_string))

print(welcome_message(u"Angstrom (Å®)".encode("latin-1"))

在设置默认编码之前,此代码将无法解码ascii编码中的“Å”,然后进入异常处理程序来猜测编码并将其正确地转换为unicode。印刷:Angstrom(Å®)经营您的业务。一旦将defaultencoding设置为utf-8,代码将会发现byte_string可以被解释为utf-8,因此它将修改数据并返回该数据:Angstrom(Ů)运行您的业务。

改变常数将会对你所依赖的模块产生巨大的影响。最好修正进出代码的数据。

扫码关注云+社区