在这里使用python 2.7 ......
我正在编码/解码一个字符串(实际上是一个字符),但是我收到一个警告:
enc.py:22: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
评估读取的行:“if(b == c)”。这是python代码和我的输出。我想如果我得到“if(b == c)”比较的警告我也会收到“if(a == c)”比较,但我没有。为什么呢?
a = "A"
b = a.encode("utf16")
c = b.decode("utf16")
print "Unencoded len(a) = " + str(len(a))
print "utf16 encoded len(a) = " + str(len(b))
print "decoded utf16 length = " + str(len(c))
print ""
print "type(a) = " + str(type(a))
print "type(b) = " + str(type(b))
print "type(c) = " + str(type(c))
print ""
if (b == a):
print " a = b"
else:
print " a != b"
if (b == c):
print " b = c"
else:
print " b != c"
if (a == c):
print " a = c"
else:
print " a != c"
这是我的输出:
Unencoded len(a) = 1
utf16 encoded len(a) = 4
decoded utf16 length = 1
type(a) = <type 'str'>
type(b) = <type 'str'>
type(c) = <type 'unicode'>
a != b
enc.py:22: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
if (b == c):
b != c
a = c
答案 0 :(得分:0)
如果您还没有看到它,这是一篇关于Python中Unicode的非常精彩的演讲/教程:
http://nedbatchelder.com/text/unipain.html
Python 2在幕后做了一些魔术,并试图来回自动转换unicode / ascii。我相信.encode()创建一个bytestring,而.decode()将它转换回utf8 / ascii。
所以b是string类型,但它是一个编码字符串。我相信正在发生的事情(有人请纠正我,如果我错了,Unicode会让我的头受伤)是这样的:
a = ascii
b =
的bytestring版本c =
的unicode版本Python认为a和b(以及b和c)是不同的,但是然后将c自动转换回ascii(或a到unicode)并认为它们匹配。
我敢打赌,Python 3会抱怨== c,因为它会更仔细地跟踪这种区别。
答案 1 :(得分:0)
嗯,这很可能是因为它在比较a和c之前转换c。我认为这是预期的行为。它在警告中说它正在尝试转换。
答案 2 :(得分:0)
此错误意味着您实际上并未比较两个unicode对象,而是将字符串对象与unicode对象进行比较。
尝试:
print type(a), type(b), type(c)
你会看到结果:
<type 'str'> <type 'str'> <type 'unicode'>
解决方案是将您要比较的内容转换为相同类型(有关详细信息,请查看unicode)。
希望这会有所帮助。答案 3 :(得分:0)
简而言之:当您通过将b
编码为utf-16创建a
时,您将创建一个非ascii字符串。 Python没有跟踪其内容的来源,所以当以后需要将b
转换为unicode时,它不知道应如何解释其内容。
详情
Python有两种存储文本的方式:作为unicode字符,其属性由python已知和理解,或作为字节序列。后者描述了python 2中的类型str
,它在python 3中被重命名为更合适的bytes
(并且unicode成为文本字符串的默认格式)。
第一次转换b = a.encode("utf16")
成功,因为当python 2在字符串中找到类似ASCII文本的字节(序号值低于255的字符)时,它假定它们 ascii文本。
就python而言, b
不是unicode文本。它包含一个表示utf16编码字符的4字节序列,但 python不跟踪其中字节序列来自。因此,当您通过将b
与unicode字符串进行比较来触发自动转换为unicode时,python会注意到它不是纯ASCII但不知道要使用哪种编码。
当然,您可以通过明确标识编码将b
转换为unicode,就像创建c
时所做的那样:
c = b.decode("utf16")