Преобразование Python 3 Строка байтов Unicode - `str (utf8_encoded_str)` обратно в unicode

Хорошо, позвольте мне сначала представить проблему.

У меня есть некоторые данные через запросы POST/GET. Данные были кодированной строкой UTF-8. Я мало знал об этом и преобразовал его только методом str(). И теперь у меня есть полная база данных "бессмысленных данных" и не удалось найти обратный путь.

Пример кода:

unicode_str - это строка, которую я должен получить

encoded_str - это строка, которую я получил с запросами POST/GET - начальные данные

bad_str - данные, которые у меня есть в базе данных на данный момент, и мне нужно получить unicode.

Итак, я знаю, как конвертировать: unicode_str= (encode) = > encoded_str= (str) = > bad_str

Но я не мог придумать решение: bad_str= (???) = > encoded_str= (decode) = > unicode_str

In [1]: unicode_str = 'Příliš žluťoučký kůň úpěl ďábelské ódy'

In [2]: unicode_str
Out[2]: 'Příliš žluťoučký kůň úpěl ďábelské ódy'

In [3]: encoded_str = unicode_str.encode("UTF-8")

In [4]: encoded_str
Out[4]: b'P\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88 \xc3\xbap\xc4\x9bl \xc4\x8f\xc3\xa1belsk\xc3\xa9 \xc3\xb3dy'

In [5]: bad_str = str(encoded_str)

In [6]: bad_str
Out[6]: "b'P\\xc5\\x99\\xc3\\xadli\\xc5\\xa1 \\xc5\\xbelu\\xc5\\xa5ou\\xc4\\x8dk\\xc3\\xbd k\\xc5\\xaf\\xc5\\x88 \\xc3\\xbap\\xc4\\x9bl \\xc4\\x8f\\xc3\\xa1belsk\\xc3\\xa9 \\xc3\\xb3dy'"

In [7]: new_encoded_str = some_magical_function_here(bad_str) ???

Ответ 1

Вы превратили объект байтов в строку, которая представляет собой просто представление объекта байтов. Вы можете получить исходный объект байта, используя ast.literal_eval() (кредиты Марку Толонену за предложение), тогда простое decode() будет делать задание.

>>> import ast
>>> ast.literal_eval(bad_str).decode('utf-8')
'Příliš žluťoučký kůň úpěl ďábelské ódy'

Поскольку вы были тем, кто сгенерировал строки, использование eval() было бы безопасным, но почему бы не быть более безопасным?

Ответ 2

Пожалуйста, не используйте eval, а вместо:

import codecs
s = 'žluťoučký'
x = str(s.encode('utf-8'))

# strip quotes
x = x[2:-1]

# unescape
x = codecs.escape_decode(x)[0].decode('utf-8')

# profit
x == s