我从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中所做的一样?
答案 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"))