以下代码在我的Windows机器上运行Python3正常运行并打印字符'é':
data = b"\xc3\xa9"
print(data.decode('utf-8'))
但是,在基于Ubuntu的docker容器上运行相同的结果会导致:
UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 0: ordinal not in range(128)
我是否需要安装任何东西来启用utf-8解码?
答案 0 :(得分:3)
问题在于print()
表达式,而不是decode()
方法。
如果仔细观察,引发的异常是Unicode En codeError,而不是 - De codeError。
每当你使用print()
函数时,Python都会将其参数转换为str
,然后将结果编码为bytes
,然后将其发送到终端(或者运行的任何Python) )。
用于编码的编解码器(例如UTF-8或ASCII)取决于环境。
在理想的情况下,
在您的情况下,您提到的Linux docker不符合第二个条件:使用的编码是ASCII,它只支持旧英文打字机上的字符。 这些是解决此问题的几个选项:
LC_ALL
设置为包含“UTF-8”的内容曾为我工作过一次。您必须将它们放在终端运行的shell的启动脚本中,例如。 的.bashrc 重新编码STDOUT,如下所示:
sys.stdout = open(sys.stdout.buffer.fileno(), 'w', encoding='utf8')
使用的编码必须与终端匹配。
sys.stdout
下面的二进制缓冲区,例如。 sys.stdout.buffer.write("é".encode('utf8'))
。这当然比print("é")
更加模板化。同样,使用的编码必须与终端匹配。print()
。使用open(fn, encoding=...)
作为输出,进度信息的日志记录模块 - 取决于脚本的交互方式,这可能是值得的(诚然,在使用日志记录模块写入STDERR时,您可能会遇到相同的编码问题)。 可能还有其他选择,但我怀疑有更好的选择。
答案 1 :(得分:2)
似乎ubuntu - 取决于版本 - 使用一个或另一个编码作为默认值,它也可能在shell和python之间有所不同。通过this posting和this blog:
因此推荐的方法似乎是告诉你的python实例使用utf-8
作为默认编码:
通过环境变量设置python源文件的默认编码:
export PYTHONIOENCODING=utf8
此外,在源文件中,您可以说明您希望明确使用的编码,因此无论环境设置如何,它都应该有效(请参阅this question + answer,python docs和PEP 263:< / p>
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
....
关于python读取的文件编码的解释,您可以在open命令中明确指定它
with open(fname, "rt", encoding="utf-8") as f:
...
并且有一些更具有一些副作用的hackish方式,但是每次明确指定它时都会保存你
import sys
# sys.setdefaultencoding() does not exist, here!
reload(sys) # Reload does the trick!
sys.setdefaultencoding('UTF8')
请在related answer和评论中阅读有关此黑客的警告。