Преобразование строки байтов в строку в кодировке base64 (вывод не является строкой байтов)

Мне было интересно, можно ли преобразовать строку байтов, которую я получил при чтении файла, в строку (так что type(output) == str). Все, что я нашел в Google до сих пор, это ответы типа Как вы base-64 кодируете изображение PNG для использования в data-uri в файле CSS?, который, кажется, будет работать в python 2 (где, если я не ошибаюсь, строки в любом случае были байтовыми строками), но больше не работает в python 3.4.

Причина, по которой я хочу преобразовать полученную строку байтов в обычную строку, заключается в том, что я хочу использовать эти данные в кодировке base64 для хранения в объекте JSON, но я продолжаю получать сообщение об ошибке, похожее на:

TypeError: b'Zm9v' is not JSON serializable

Вот минимальный пример того, где что-то идет не так:

import base64
import json
data = b'foo'
myObj = [base64.b64encode(data)]
json_str = json.dumps(myObj)

Итак, мой вопрос: есть ли способ преобразовать этот объект типа bytes в объект типа str, сохраняя при этом кодировку base64 (поэтому в этом примере я хочу, чтобы результат был ["Zm9v"]. Возможно ли это?


person Joeytje50    schedule 21.10.2015    source источник


Ответы (2)


Что работает для меня, так это изменить строку b64encode на:

myObj = [base64.b64encode(data).decode('ascii')]

Это объясняется в https://stackoverflow.com/a/42776711:

base64 был намеренно классифицирован как бинарное преобразование... В Python 3 было конструктивным решением принудительно разделить байты и текст и запретить неявные преобразования.

Принятый ответ у меня не работает (Python 3.9) и выдает ошибку:

Traceback (most recent call last):
  File "/tmp/x.py", line 4, in <module>
    myObj = [base64.b64encode(data)]
  File "/usr/lib64/python3.9/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
person jmou    schedule 20.11.2020
comment
Я только что попробовал принятый ответ в python 3.6, и, похоже, он все еще там работает. Есть идеи, почему между этими двумя второстепенными версиями могут быть критические изменения? Обновления второстепенных версий не должны иметь критических изменений, поэтому мне любопытно посмотреть. Не могли бы вы проверить принятый ответ и в python3.6, чтобы посмотреть, сможете ли вы воспроизвести там ошибку? - person Joeytje50; 24.11.2020
comment
У меня тоже не работает Python 3.6: ```$ docker run --rm -it python:3.6 Python 3.6.12 (по умолчанию, 18 ноября 2020 г., 14:46:32) [GCC 8.3.0] на linux Type помощь, авторские права, кредиты или лицензии для получения дополнительной информации. ››› import base64 ››› import json ››› data = b'foo'.decode('UTF-8') ››› myObj = [base64.b64encode(data)] Traceback (последний последний вызов): File ‹stdin›, строка 1, в ‹module› Файл /usr/local/lib/python3.6/base64.py, строка 58, в b64encode encoded = binascii.b2a_base64(s, newline=False) TypeError: a bytes-like требуется объект, а не 'str' ``` - person jmou; 25.11.2020
comment
Извините за плохое оформление! Это просто я запускаю команды в контейнере Python 3.6 Docker. - person jmou; 25.11.2020

Пытаться

data = b'foo'.decode('UTF-8')

вместо

data = b'foo'

чтобы преобразовать его в строку.

person Victor - Reinstate Monica    schedule 21.10.2015