Байты в строке Unicode Python

В Python 2 строки Unicode могут содержать как unicode, так и байты:

a = u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \xd0\xb5\xd0\xba'

Я понимаю, что это абсолютно не то, что следует писать] в его собственном коде, но это строка, с которой мне приходится иметь дело.

Байты в приведенной выше строке имеют формат UTF-8 для ек(Юникод \u0435\u043a).

Моя цель - получить строку Unicode, содержащую все в Unicode, то есть Русский ек( \u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u0435\u043a ).

Кодирование в UTF-8 дает

>>> a.encode('utf-8')
'\xd0\xa0\xd1\x83\xd1\x81\xd1\x81\xd0\xba\xd0\xb8\xd0\xb9 \xc3\x90\xc2\xb5\xc3\x90\xc2\xba'

Который затем декодируется из UTF-8 и дает исходную строку с байтами в них, что нехорошо:

>>> a.encode('utf-8').decode('utf-8')
u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \xd0\xb5\xd0\xba'

Однако я нашел хакерский способ решить проблему:

>>> repr(a)
"u'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \\xd0\\xb5\\xd0\\xba'"
>>> eval(repr(a)[1:])
'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \xd0\xb5\xd0\xba'
>>> s = eval(repr(a)[1:]).decode('utf8')
>>> s
u'\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \u0435\u043a'
# Almost there, the bytes are proper now but the former real-unicode characters
# are now escaped with \u's; need to un-escape them.
>>> import re
>>> re.sub(u'\\\\u([a-f\\d]+)', lambda x : unichr(int(x.group(1), 16)), s)
u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u0435\u043a' # Success!

Это прекрасно работает, но выглядит очень хакерским из-за использования eval, repr, а затем дополнительного регулярного выражения строкового представления Юникода. Есть ли более чистый способ?

33
задан Etienne Perot 23 March 2012 в 20:05
поделиться