Python Unicode: 为什么在一台机器上有效,而另一台机器上有时失效?
我发现 Python 中的 Unicode 处理真的很麻烦,为什么 Python 不把所有字符串都用 utf-8 编码呢?我在中国,需要使用一些用 ASCII 无法表示的中文字符串。我用 u''
来表示一个字符串,这在我的 Ubuntu 机器上运行得很好,但在另一台 Ubuntu 机器上(是 linode.com 提供的 VPS),有时候就会出错。错误信息是:
UnicodeDecodeError: 'ascii' 编码 无法解码字节 0xe9 在位置 0: 序号不在范围内(128)
我使用的代码是:
self.talk(user.record["fullname"] + u"准备好了")
4 个回答
因为在Python 2.x版本中,默认的编码是ASCII,除非你手动去更改它。这里有一个简单的办法,可以在你的代码之前加上这个内容:
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
这样就可以把Python的默认编码改成UTF-8了。
你需要尽早把所有不是Unicode的字符串解码。尽量确保你的内存里没有存储UTF-8的字节串,而只有Unicode对象。比如,确保在创建用户记录的时候,所有的元素都转换成Unicode,这样就不会出现类似的错误。或者你可以直接使用Python 3,因为在这个版本里,混合使用这两种字符串是比较困难的。
大家都知道的那个 UnicodeDecodeError
错误,通常发生在你进行字符串操作的时候,比如你刚才做的那样:
user.record["fullname"] + u" 准备好了"
因为你在把一个普通字符串(str)和一个Unicode字符串拼接在一起,所以Python会自动把普通字符串转换成Unicode字符串,然后再进行拼接。这种转换是这样进行的:
unicode(user.record["fullname"]) + u" 准备好了"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Problem
问题就出在这里,因为当你使用 unicode(something)
时,Python会用默认的编码方式来解码这个字符串。在Python 2.*中,默认编码是ASCII。如果你的字符串 user.record["fullname"]
中包含一些非ASCII字符,就会出现著名的 UnicodeDecodeError
错误。
那么你该如何解决这个问题呢:
# Decode the str to unicode using the right encoding
# here i used utf-8 because mostly is the right one but maybe it not (another problem!!!)
a = user.record["fullname"].decode('utf-8')
self.talk(a + u" 准备好了")
顺便说一下,现在在Python 3中,默认编码是utf-8,还有一点就是你不能把Unicode字符串和普通字符串(在Python 3中称为字节)拼接在一起,所以不再会有这种自动转换的情况了。