У вас 3, 4 или 5 проблем ... но repr()
и unicodedata.name()
ваши друзья;они однозначно показывают вам именно то, что вы получили, без путаницы, порожденной людьми с различными консольными кодировками, сообщающими результаты print fubar
.
Резюме: либо (a) вы начинаете с объекта Unicode и применяете кавычкиили (b) вы начинаете с объекта str, и ваша консольная кодировка не UTF-8.
Если, как вы говорите, вы начинаете с объекта Unicode:
>>> s0 = u'%C3%A7%C3%B6asd+fjkls%25asd'
>>> print repr(s0)
u'%C3%A7%C3%B6asd+fjkls%25asd'
это случайная ерунда.Если вы примените к нему urllibX.unquote_YYYY()
, вы получите еще один бессмысленный объект в кодировке Unicode (u'\xc3\xa7\xc3\xb6asd+fjkls%asd'
), который может вызвать показанные симптомы при печати.Вы должны немедленно преобразовать ваш исходный объект Unicode в объект str:
>>> s1 = s0.encode('ascii')
>>> print repr(s1)
'%C3%A7%C3%B6asd+fjkls%25asd'
, затем вы должны заключить его в кавычки:
>>> import urllib2
>>> s2 = urllib2.unquote(s1)
>>> print repr(s2)
'\xc3\xa7\xc3\xb6asd+fjkls%asd'
Глядя на первые 4 байта, он закодирован в UTF-8.Если вы сделаете print s2
, все будет выглядеть нормально, если ваша консоль ожидает UTF-8, но если она ожидает ISO-8859-1 (он же латинский1), вы увидите свой симптоматический мусор (первый символ будет A-тильда).Давайте на минутку запаркуем эту мысль и преобразуем ее в объект Unicode:
>>> s3 = s2.decode('utf8')
>>> print repr(s3)
u'\xe7\xf6asd+fjkls%asd'
и проверим, чтобы увидеть, что мы на самом деле получили:
>>> import unicodedata
>>> for c in s3[:6]:
... print repr(c), unicodedata.name(c)
...
u'\xe7' LATIN SMALL LETTER C WITH CEDILLA
u'\xf6' LATIN SMALL LETTER O WITH DIAERESIS
u'a' LATIN SMALL LETTER A
u's' LATIN SMALL LETTER S
u'd' LATIN SMALL LETTER D
u'+' PLUS SIGN
Похоже, что вы сказалиты ожидалТеперь мы подошли к вопросу его отображения на вашей консоли.Примечание: не волнуйтесь, когда видите «cp850»;Я делаю это переносимо, и просто так происходит в командной строке в Windows.
>>> import sys
>>> sys.stdout.encoding
'cp850'
>>> print s3
çöasd+fjkls%asd
Примечание: объект unicode был явно закодирован с использованием sys.stdout.encoding.К счастью, все символы Unicode в s3
представимы в этой кодировке (и cp1252 и latin1).