一个简单的例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import traceback
e_u = u'abc'
c_u = u'中国'
print sys.getdefaultencoding()
try:
print e_u.decode('utf-8')
print c_u.decode('utf-8')
except Exception as e:
print traceback.format_exc()
reload(sys)
sys.setdefaultencoding('utf-8')
print sys.getdefaultencoding()
try:
print e_u.decode('utf-8')
print c_u.decode('utf-8')
except Exception as e:
print traceback.format_exc()
输出:
^{pr2}$几天来,当我想彻底理解python中的编解码器时,一些问题困扰着我,我想确定我的想法是正确的:
在ascii
默认编码下,u'abc'.decode('utf-8')
没有错误,但是{
我想当做u'中国'.decode('utf-8')
时,Python检查发现{u'中国'.encode(sys.getdefaultencoding())
,这会引起问题,异常是UnicodeEncodeError
,解码时没有出错。在
但是u'abc'
与'abc'
(<;128)具有相同的代码点,因此没有错误。
在python2.x中,Python内部如何存储变量值?如果字符串中的所有字符<;128,则视为ascii
,如果>;128,则视为utf-8
?在
In [4]: chardet.detect('abc')
Out[4]: {'confidence': 1.0, 'encoding': 'ascii'}
In [5]: chardet.detect('abc中国')
Out[5]: {'confidence': 0.7525, 'encoding': 'utf-8'}
In [6]: chardet.detect('中国')
Out[6]: {'confidence': 0.7525, 'encoding': 'utf-8'}
简短回答
您必须使用
encode()
,或者不使用它。不要将decode()
与unicode字符串一起使用,这是没有意义的。而且,sys.getdefaultencoding()
在这里也没有任何帮助。在冗长的回答,第一部分:如何正确地做?
如果您定义:
那么
c_u
已经是一个unicode字符串,也就是说,它已经被Python解释器使用-*- coding: utf-8 -*-
声明从(源文件的)字节字符串解码为unicode字符串。在如果执行:
^{pr2}$您的字符串将被编码回UTF-8,并将该字节字符串发送到标准输出。请注意,这通常是自动发生的,因此您可以将其简化为:
长时间的回答,第二部分:c嫒u.decode()有什么问题?
如果执行
c_u.decode()
,Python将请注意,如果您的对象首先是unicode字符串,那么这没有任何意义—您只需前后转换它。但为什么会失败呢?好吧,这是Python的一个奇怪的功能,第一步(1.),即从unicode字符串到字节字符串的任何隐式转换,通常都使用sys.getdefaultencoding(),这反过来又默认为ASCII字符集。换句话说
大致翻译为:
这就是它失败的原因。在
请注意,虽然您可能想更改默认编码,但不要忘记,其他第三方库可能包含类似的问题,如果默认编码与ASCII不同,则可能会中断。在
话虽如此,我坚信,如果Python一开始没有定义
unicode.decode()
,情况会更好。Unicode字符串已经被解码了,没有必要再次解码,尤其是Python的解码方式。在相关问题 更多 >
编程相关推荐