в base64.encodestring не в Python 3
следующий фрагмент кода успешно выполняется на компьютере python 2:
base64_str = base64.encodestring('%s:%s' % (username,password)).replace('n', '')
Я пытаюсь перенести его на Python 3, но когда я это делаю, я сталкиваюсь со следующей ошибкой:
>>> a = base64.encodestring('{0}:{1}'.format(username,password)).replace('n','')
Traceback (most recent call last):
File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 519, in _input_type_check
m = memoryview(s)
TypeError: memoryview: str object does not have the buffer interface
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 548, in encodestring
return encodebytes(s)
File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 536, in encodebytes
_input_type_check(s)
File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 522, in _input_type_check
raise TypeError(msg) from err
TypeError: expected bytes-like object, not str
Я попытался найти примеры использования encodestring, но не смог найти хороший документ. Я упускаю что-то очевидное? Я запускаю это на RHEL 2.6.18-371.11.1.el5
3 ответов
вы можете encode()
строка (чтобы преобразовать ее в байтовую строку), прежде чем передать ее в base64.encodestring
. Пример -
base64_str = base64.encodestring(('%s:%s' % (username,password)).encode()).decode().replace('\n', '')
чтобы расширить ответ Ананда (что совершенно правильно), Python 2 сделал небольшое различие между "вот строка, которую я хочу рассматривать как текст" и "вот строка, которую я хочу рассматривать как последовательность 8-битных байтовых значений". Python 3 твердо различает два и не позволяет вам смешивать их: первый -str
тип, и последний является bytes
тип.
когда вы кодируете строку Base64, вы на самом деле не обрабатываете строку как текст, вы обрабатываете ее как ряд 8-битных байтовых значений. Вот почему вы получаете ошибку от base64.encodestring()
в Python 3: потому что это операция, которая имеет дело с строки символов 8-битный байт, и поэтому вы должны передать ей параметр типа bytes
вместо параметра типа str
.
поэтому, чтобы преобразовать ваш str
объект в bytes
объект, вы должны вызвать его encode()
метод, чтобы превратить его в набор 8-битных байтовых значений, в любой кодировке Unicode у вас есть выбран для использования. (Который должен быть UTF-8, Если у вас нет очень специфический причина выбрать что-то другое, но это другая тема).
в Python 3 encodestring docs говорится:
деф encodestring(с): """Устаревший псевдоним encodebytes ().""" импорт предупреждений предупреждение.warn ("encodestring () - устаревший псевдоним, используйте encodebytes ()", DeprecationWarning, 2) возврат encodebytes (s)
вот рабочий код для Python 3.5.1, он также показывает, как кодировать url:
def _encodeBase64(consumer_key, consumer_secret):
"""
:type consumer_key: str
:type consumer_secret: str
:rtype str
"""
# 1. URL encode the consumer key and the consumer secret according to RFC 1738.
dummy_param_name = 'bla'
key_url_encoded = urllib.parse.urlencode({dummy_param_name: consumer_key})[len(dummy_param_name) + 1:]
secret_url_encoded = urllib.parse.urlencode({dummy_param_name: consumer_secret})[len(dummy_param_name) + 1:]
# 2. Concatenate the encoded consumer key, a colon character “:”, and the encoded consumer secret into a single string.
credentials = '{}:{}'.format(key_url_encoded, secret_url_encoded)
# 3. Base64 encode the string from the previous step.
bytes_base64_encoded_credentials = base64.encodebytes(credentials.encode('utf-8'))
return bytes_base64_encoded_credentials.decode('utf-8').replace('\n', '')
(Я уверен, что это может быть более кратким, я новичок в Python...)
также смотри:http://pythoncentral.io/encoding-and-decoding-strings-in-python-3-x/