a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
Что там происходит?
edit = Извините, это была моя ошибка. Это все еще ложь. Я использую Python 2.6 на Ubuntu 10.04.
a = {"a":"çö"}
b = "çö"
a['a']
>>> '\xc3\xa7\xc3\xb6'
b.decode('utf-8') == a['a']
>>> False
Что там происходит?
edit = Извините, это была моя ошибка. Это все еще ложь. Я использую Python 2.6 на Ubuntu 10.04.
Либо напишите вот так:
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'çö'
и a['a'] == 'çö'
, поэтому вы делаете следующее сравнение:
u'çö' == 'çö'
Один из объектов имеет тип unicode
, другой - тип str
, поэтому для выполнения сравнения str
преобразуется в unicode
, а затем два объекта unicode
в сравнении. Он отлично работает в случае чисто ASCII-строк, например: u'a' == 'a'
, так как unicode('a') == u'a'
.
Однако он не работает в случае u'çö' == 'çö'
, так как unicode('çö')
возвращает следующую ошибку: UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xc3 в позиции 0: порядковый номер не в диапазоне (128), и, следовательно, целое сравнение возвращает False и выдает следующее предупреждение: UnicodeWarning: Unicode равное сравнение не удалось преобразовать оба аргумента в Unicode - интерпретируя их как неравные.
b
является string
, a
является dict
Вы хотите (я верю):
b == a['a']
UTF-8 - это кодировка, используемая для записи текста в Unicode в файлах. Однако в Python вы работаете с объектами, которые имеют фиксированный способ представления текста в Unicode, и таким образом это не UTF-8.
Вы все еще можете сравнить строки Unicode в Python, но это не связано с UTF-8, за исключением того, что если вы хотите поместить константы в эти строки Unicode, вам нужно будет закодировать текст файла, содержащего ваш исходный код, в UTF-8. Как только выполняется оператор присваивания, строка больше не является UTF-8, но теперь является внутренним представлением Python.
Кстати, если вы делаете сравнения с Unicode, вы, вероятно, захотите использовать модуль unicodedata и нормализовать строки до того, как будут выполнены сравнения.
Try b == a ['a']
Вы сравниваете строку с dict.
>>> a = {"a":"çö"}
>>> b = "çö"
>>> a == b
False
>>> a['a'] == b
True
Если вы сравните строку (b) с элементом a (a ['a']), вы получите желаемый результат.
Убедитесь, что ваш код находится в UTF-8 (NOT 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_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, все "строки" теперь являются объектами "unicode" (для кодирования файла), если они не являются "добавленными" с ab (для эмулирования разделения строк/байтов в Python 3.X).
NullUserException прав, что это должно быть правильно:
b == a['a']
Вы все еще получаете "False", потому что вы декодируете одну сторону как utf-8 (создавая строку Unicode), в то время как другая сторона остается закодированной байтовой строкой utf-8.