如何解决Python 3.6中的UnicodeDecodeError?

问题描述 投票:0回答:7

我从 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 中所做的那样?

python python-3.x linux ubuntu unicode
7个回答
26
投票

听起来您的语言环境已损坏 并且还有另一个字节->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 仍然抛出错误,请使用堆栈跟踪更新您的问题。您很可能正在进行隐式转换。


6
投票

我在基于 Ubuntu 18.04 的 Docker 容器中使用 Python 时遇到了这个问题。 这似乎是一个区域设置问题,通过将以下内容添加到 Dockerfile 来解决:

ENV LANG C.UTF-8

3
投票

对于使用 pickle 加载之前在 python 2 中保存的文件并收到 UnicodeDecodeError 的每个人,请尝试设置 pickle

encoding
参数:

with open("./data.pkl", "rb") as data_file:
    samples = pickle.load(data_file, encoding='latin1')

1
投票

对于仅 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
。您的终端程序似乎没有执行此操作。


-2
投票

Python 3(包括3.6)已经支持Unicode。这是文档 - https://docs.python.org/3/howto/unicode.html

所以你不需要像Python 2.7那样强制支持Unicode。尝试正常运行您的代码。如果读取 Unicode 文本文件时出现任何错误,则需要在读取文件时使用

encoding='utf-8'
参数。


-2
投票

对于使用 python3.6 的 docker,使用

LANG=C.UTF-8 python or jupyter xxx
对我有用,感谢@Daniel 和 @zhy


-3
投票

我的意思是你可以编写这样的自定义函数: (我知道这不是最佳选择)


import sys

def printUTF8(input):
    print(input.encode("utf-8"))
© www.soinside.com 2019 - 2024. All rights reserved.