我从 Python 2.7 切换到 Python 3.6。
我有处理一些非英语内容的脚本。
我通常通过 Cron 以及终端运行脚本。
我的 Python 2.7 脚本中有 UnicodeDecodeError,我用这个解决了。
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
现在在Python 3.6中,它不起作用。我有像
print("Here %s" % (myvar))
这样的打印语句,它会抛出错误。我可以通过将其替换为 myvar.encode("utf-8")
来解决这个问题,但我不想用每个 print 语句来写。
我在终端中做了
PYTHONIOENCODING=utf-8
,但仍然存在这个问题。
有没有更干净的方法来解决 Python 3.6 中的
UnicodeDecodeError
问题?
有没有办法告诉Python3以utf-8打印所有内容?就像我在 Python2 中所做的那样?
听起来您的语言环境已损坏 并且还有另一个字节->Unicode 问题。你对 Python 2.7 所做的事情只是一个 hack,它仅仅掩盖了真正的问题(这就是你必须
reload sys
才能让它工作的原因)。
要修复您的区域设置,请尝试从命令行输入
locale
。它应该看起来像:
LANG=en_GB.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_ALL=
locale
取决于 LANG
设置是否正确。 Python 有效地使用 locale
来确定写入 stdout 时要使用的编码。如果无法解决,则默认为 ASCII。
您应该首先尝试修复您的区域设置。如果出现
locale
错误,请确保您已安装适合您所在地区的正确语言包。
如果所有其他方法都失败,您始终可以通过设置
PYTHONIOENCODING=UTF-8
来修复 Python。这应该作为最后的手段,因为您将再次掩盖问题。
如果设置
PYTHONIOENCODING
后 Python 仍然抛出错误,请使用堆栈跟踪更新您的问题。您很可能正在进行隐式转换。
我在基于 Ubuntu 18.04 的 Docker 容器中使用 Python 时遇到了这个问题。 这似乎是一个区域设置问题,通过将以下内容添加到 Dockerfile 来解决:
ENV LANG C.UTF-8
对于使用 pickle 加载之前在 python 2 中保存的文件并收到 UnicodeDecodeError 的每个人,请尝试设置 pickle
encoding
参数:
with open("./data.pkl", "rb") as data_file:
samples = pickle.load(data_file, encoding='latin1')
对于仅 Python 的解决方案,您必须重新创建
sys.stdout
对象:
import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
此后,正常的
print("hello world")
应自动编码为 UTF-8。
但是你应该尝试找出为什么你的终端设置为如此奇怪的编码(Python 只是试图采用这种编码)。也许您的操作系统配置有误。
编辑:在我的测试中,取消设置环境变量
LANG
为我的标准输出编码产生了这个奇怪的设置:
LANG= python3
import sys
sys.stdout.encoding
印刷
'ANSI_X3.4-1968'
。
所以我想你可能想将
LANG
设置为类似
en_US.UTF-8
。您的终端程序似乎没有执行此操作。
Python 3(包括3.6)已经支持Unicode。这是文档 - https://docs.python.org/3/howto/unicode.html
所以你不需要像Python 2.7那样强制支持Unicode。尝试正常运行您的代码。如果读取 Unicode 文本文件时出现任何错误,则需要在读取文件时使用
encoding='utf-8'
参数。
对于使用 python3.6 的 docker,使用
LANG=C.UTF-8 python or jupyter xxx
对我有用,感谢@Daniel 和 @zhy
我的意思是你可以编写这样的自定义函数: (我知道这不是最佳选择)
import sys
def printUTF8(input):
print(input.encode("utf-8"))