使用python 2.7.3,以下内容不会引发TypeError。
>>> unicode(u'')
u''
但是传递errors
参数会引发TypeError: decoding Unicode is not supported
>>> unicode(u'',errors='replace')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: decoding Unicode is not supported
>>> unicode(u'',errors='ignore')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: decoding Unicode is not supported
>>> unicode(u'',errors='strict')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: decoding Unicode is not supported
任何猜测为什么这种行为如此不同? IMO,这是unicode
函数的一个令人惊讶的怪癖。
浏览python源代码,(我只是猜测我正在遵循正确的代码路径)
PyUnicode_FromEncodedObject
的{{3}}中,我们找到错误字符串"decoding Unicode is not supported"
。如果PyUnicode_Check(obj)
返回非0,则设置错误字符串。
,PyUnicode_Check
评估表达式(((Py_TYPE(obj))->tp_flags & (Py_TPFLAGS_UNICODE_SUBCLASS)) != 0)
,
但是,由于传递了errors
参数,我无法找到Python代码采用不同代码路径的位置。
答案 0 :(得分:2)
unicode
(docs)是一个将字符串转换为Python中字符串的unicode表示的函数。但是,如果传入编码或错误参数,则行为会有所不同。
如果给出编码和/或错误,unicode()将解码对象 它可以是8位字符串,也可以是使用的字符缓冲区 用于编码的编解码器。 encoding参数是一个给出名称的字符串 编码;如果编码未知,则引发LookupError。 错误处理是根据错误完成的;这指定了 处理输入编码中无效的字符。如果 错误是'严格'(默认值),错误会引发ValueError, 而'ignore'的值会导致错误被忽略,而a 'replace'的值导致官方的Unicode替换字符, U + FFFD,用于替换不能输入的字符 解码。另请参阅编解码器模块。
如果没有给出可选参数,unicode()将模仿 str()的行为,除了它返回Unicode字符串而不是 8位字符串。更准确地说,如果object是Unicode字符串或 子类它将返回该Unicode字符串而无需任何额外的 解码应用。
您无法将u''
转换为unicode的原因是因为它已经是unicode表示。当Python尝试使用ascii编解码器(默认编解码器,因为你没有指定一个)解码它时,它意识到该字符串已经是Unicode,并抛出一个错误(“Python:Oi你为什么要尝试转换unicode串到unicode?“)
如果没有指定错误参数,正如您在文档中看到的那样,Python可以将unicode字符串转换为unicode。如果它已经是unicode,它将返回unicode字符串而不需要任何额外的解码。
standard link让人们了解unicode是什么。
如果您确实希望能够执行此操作(例如,如果您想编写接受常规字符串和unicode字符串的代码),则在将字符串转换回Unicode之前对其进行编码。
示例:
>>> unicode(u''.encode('ascii', errors='replace'))
如果您想使用其他编码(ascii是默认编码):
>>> unicode(u''.encode('utf-8', errors='replace'), 'utf-8')
答案 1 :(得分:0)
我认为unicode()
函数应该采用string
类型的数据,而不是unicode
类型的数据:
unicode()构造函数具有签名unicode(string [,encoding,errors])。它的所有参数都应该是8位字符串。第一个参数使用指定的编码转换为Unicode; 如果您不使用编码参数,则使用ASCII编码进行转换,因此大于127的字符将被视为错误:
>>> unicode('abcdef')
u'abcdef'
>>> s = unicode('abcdef')
>>> type(s)
<type 'unicode'>
>>> unicode('abcdef' + chr(255))
Traceback (most recent call last):
...
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
ordinal not in range(128)
u''
正在编码空字符串(我认为它不是大于127的字符)。没有编码参数应该没问题,但我相信unicode
会引发错误,因为它不应该定期接受Unicode。
我现在正在尽力猜测这一点,所以任何更正都会受到赞赏。