19
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'

b.decode('utf-8') == a['a']
>>> False

里面发生了什么?

编辑=对不起,这是我的错误。它仍然是错误的。我在 Ubuntu 10.04 上使用 Python 2.6。

4

7 回答 7

30

可能的解决方案

要么这样写:

a = {"a": u"çö"}
b = "çö"
b.decode('utf-8') == a['a']

或者像这样(你也可以跳过.decode('utf-8')两边):

a = {"a": "çö"}
b = "çö"
b.decode('utf-8') == a['a'].decode('utf-8')

或者像这样(我的建议):

a = {"a": u"çö"}
b = u"çö"
b == a['a']

解释

根据蒂姆的评论更新。 在您的原始代码中,b.decode('utf-8') == u'çö'and a['a'] == 'çö',因此您实际上是在进行以下比较:

u'çö' == 'çö'

其中一个对象是 type unicode,另一个是 type str,所以为了执行比较,将str转换为unicode然后unicode比较两个对象。它在纯 ASCII 字符串的情况下工作正常,例如:u'a' == 'a', since unicode('a') == u'a'.

但是,在 的情况下它会失败u'çö' == 'çö',因为unicode('çö')返回以下错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128),因此整个比较返回 False 并发出以下警告: UnicodeWarning: Unicode 相等比较未能将两个参数转换为 Unicode - 将它们解释为不相等

于 2010-08-03T20:00:16.297 回答
5

b是一个stringa是一个dict

你想要(我相信):

b == a['a']

于 2010-08-03T19:41:49.183 回答
4

UTF-8 是一种用于在文件中记录 Unicode 文本的编码。但是,在 Python 中,您使用的对象具有表示 Unicode 文本的固定方式,而这种方式不是 UTF-8。

你仍然可以在 Python 中比较 Unicode 字符串,但这与 UTF-8 无关,除非你想将常量放入这些 Unicode 字符串中,那么你需要将包含你的源代码的文件的文本编码为 UTF- 8. 一旦执行了赋值运算符,字符串就不再是 UTF-8,而是 Python 的内部表示。

顺便说一句,如果您正在使用 Unicode 进行比较,您可能需要使用 unicodedata 模块并在比较完成之前对字符串进行规范化。

于 2010-08-03T20:48:55.973 回答
2

试试 b == a['a']

于 2010-08-03T19:42:00.043 回答
2

您正在将字符串与字典进行比较。

>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True

如果您将字符串 (b) 与 a (a['a']) 的成员进行比较,那么您将得到所需的结果。

于 2010-08-03T19:42:23.303 回答
0

确保您的代码是 UTF-8(不是 Latin-1)和/或使用这样的编码行:

#! /usr/bin/python
# -*- coding: utf-8 -*-
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b.decode('utf-8') == a['a'].decode('utf-8')

如果您全面使用 unicode,您可以从未来导入 unicode_literals 并减少编码的烦恼:

#! /usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
a = {"a": u"çö"}
b = "çö"
assert b == a['a']
assert b == a['a']
assert b.encode('utf-8') != a['a']
assert b.encode('utf-8') == a['a'].encode('utf-8')

如果文件使用 unicode_literals,则所有“字符串”现在都是 u“unicode”对象(根据文件的编码),如果它们不是 b“前置”ab (以模拟 Python 3.X 中拆分的字符串/字节) .

于 2010-08-03T20:51:39.563 回答
0

NullUserException 是正确的,这应该是正确的:

b == a['a']

您仍然会得到“False”,因为您将一侧解码为 utf-8(创建 Unicode 字符串),而另一侧仍然是 utf-8 编码的字节字符串。

于 2010-08-04T19:12:17.963 回答