Как уже говорили другие, юникод и utf-8 - это не одно и то же. UTF-8 является одним из многих кодировок для Unicode.
Думайте о unicode
объектах как о "некодированных" строках юникода, тогда как string
объекты кодируются в определенной кодировке (к сожалению, строковые объекты не имеют атрибута, который говорит вам, как они кодируются).
val.encode("utf-8")
преобразует этот объект Unicode в строковый объект в кодировке utf-8.
В Python 2.6 это необходимо, поскольку urllib
не может правильно обрабатывать юникод.
>>> import urllib
>>> urllib.quote(u"")
''
>>> urllib.quote(u"ä")
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib.py:1216: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
res = map(safe_map.__getitem__, s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib.py", line 1216, in quote
res = map(safe_map.__getitem__, s)
KeyError: u'\xe4'
>>> urllib.quote(u"ä".encode("utf-8"))
'%C3%A4'
Однако в Python 3.x, где все строки в Unicode (эквивалент Python 3 для закодированной строки является bytes
объектом), в этом больше нет необходимости.
>>> import urllib.parse
>>> urllib.parse.quote("ä")
'%C3%A4'