如何在Python 3.6中解决UnicodeDecodeError?

时间:2018-06-25 14:50:39

标签: python python-3.x unicode

我从Python 2.7切换到Python 3.6。

我有处理某些非英语内容的脚本。

我通常通过Cron以及在Terminal中运行脚本。

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

6 个答案:

答案 0 :(得分:3)

听起来您的语言环境已损坏,并且还有另一个字节-> Unicode问题。您为Python 2.7做的事情是只掩盖了真正的问题的黑客(这是您必须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来算出向标准输出写入时要使用的编码。如果无法计算,则默认为ASCII。

您应该首先尝试修复您的语言环境。如果出现locale错误,请确保您安装了适合您所在地区的语言包。

如果其他所有方法均失败,则始终可以通过设置PYTHONIOENCODING=UTF-8来修复Python。这将被用作最后的手段,因为您将再次掩盖问题。

如果在设置PYTHONIOENCODING之后Python仍然抛出错误,请使用stacktrace更新您的问题。您有可能正在进行隐式转换。

答案 1 :(得分:1)

对于仅Python的解决方案,您将不得不重新创建sys.stdout对象:

import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())

此后,应将普通的print("hello world")自动编码为UTF-8。

但是您应该尝试找出为什么将您的终端设置为这种奇怪的编码(Python只是试图采用这种编码)。也许您的操作系统配置不正确。

编辑:在我的测试中,取消设置环境变量LANG对我的stdout编码产生了这种奇怪的设置:

LANG= python3
import sys
sys.stdout.encoding

打印'ANSI_X3.4-1968'

因此,我想您可能希望将LANG设置为类似 en_US.UTF-8。您的终端程序似乎没有执行此操作。

答案 2 :(得分:1)

对于使用 pickle 加载以前保存在 python 2 中的文件并获得 UnicodeDecodeError 的每个人,请尝试设置 pickle encoding 参数:

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

答案 3 :(得分:0)

在基于Ubuntu 18.04的Docker容器中使用Python时遇到此问题。 这似乎是一个语言环境问题,已通过在Dockerfile中添加以下内容解决了该问题:

 socket = IO.socket("http://192.168.0.101:3000");

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {
                    System.out.println("Connected");
                    socket.emit("message","test");
                }

            }).on("message", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    System.out.println("Message : "+args[0]);
                }


            }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {
                    System.out.println("Socket disconnected");
                }

            }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    System.out.println("Error In Socket Connection "+args[0]);
                }
            });
            socket.connect();

答案 4 :(得分:-2)

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

因此,您无需强制像python 2.7这样的Unicode支持。尝试正常运行您的代码。如果您在读取Unicode文本文件时遇到任何错误,则在读取文件时需要使用encoding='utf-8'参数。

答案 5 :(得分:-3)

我的意思是您可以编写这样的自定义函数: (我知道不是最优的)


import sys

def printUTF8(input):
    print(input.encode("utf-8"))