#python #python-3.x #python-2.5
#python #python-3.x #python-2.5
Вопрос:
Я пишу модуль, который должен работать как в Python 2, так и в Python 3, и мне нужно определить двоичную строку.
Обычно это было бы что-то вроде data = b'abc'
, но этот код не работает на Python 2.5 с недопустимым синтаксисом.
Как я могу написать приведенный выше код таким образом, чтобы он работал во всех версиях Python 2.5
Примечание: это должно быть binary
(оно может содержать любые символы, 0xFF), это очень важно.
Комментарии:
1. Двоичная строка? Вы имеете в виду
bytes
объект?2.
b"abc"
Синтаксис иbytes()
конструктор были добавлены в Python 2.6 .3. Да, я имел в виду байты.
4. При поиске python 2 и python 3 различными способами поиска в Google для этого на первой странице результатов поиска появятся как библиотека six, так и моя книга, в которой есть по существу похожие рабочие решения для этого. Тем не менее, кажется, никто не знает, что любой из них существует. Как мы можем это исправить? Распространяйте информацию!
Ответ №1:
Я бы рекомендовал следующее:
from six import b
Конечно, для этого требуется модуль six.
Если вы этого не хотите, вот другая версия:
import sys
if sys.version < '3':
def b(x):
return x
else:
import codecs
def b(x):
return codecs.latin_1_encode(x)[0]
Эти решения (по сути, одинаковые) работают, являются чистыми, настолько быстрыми, насколько вы собираетесь получить, и могут поддерживать все 256-байтовые значения (чего не может ни одно из других решений здесь).).
Ответ №2:
Если строка содержит только символы ASCII, вызовите encode
. Это даст вам a str
в Python 2 (точно так b'abc'
же) и a bytes
в Python 3:
'abc'.encode('ascii')
Если нет, вместо того, чтобы помещать двоичные данные в исходный код, создайте файл данных, откройте его 'rb'
и прочитайте из него.
Комментарии:
1. Как вы и подозревали, у меня есть несколько очень маленьких двоичных блоков, поэтому использование файлов для их хранения не является вариантом. И да, они имеют значения, отличные от ascii.
2. Итак, как на самом деле выглядят строки? Если это строки, понятные человеку, расшифруйте их с помощью правильной кодировки. Если нет, то используйте
base64
.3. Создать файл и прочитать из него? Сложное решение простой проблемы. Извините, -1.
4. (И использование ascii ограничено без причины, вместо этого используйте latin1).
5. @LennartRegebro: Это не сработало бы в Python 2; попробуйте
'xff'.encode('latin1')
.
Ответ №3:
Вы могли бы хранить данные в кодировке base64.
Первым шагом будет преобразование в base64:
>>> import base64
>>> base64.b64encode(b"x80xFF")
b'gP8='
Это должно быть сделано один раз, и использование b
или нет зависит от версии Python, которую вы используете для этого.
На втором шаге вы помещаете эту байтовую строку в программу без b
. Тогда гарантируется, что она работает в py2 и py3.
import base64
x = 'gP8='
base64.b64decode(x.encode("latin1"))
дает вам a str
'x80xff'
в 2.6 (также должно работать в 2.5) и a b'x80xff'
в 3.x.
В качестве альтернативы двум шагам, описанным выше, вы можете сделать то же самое с шестнадцатеричными данными, вы можете сделать
import binascii
x = '80FF'
binascii.unhexlify(x) # `bytes()` in 3.x, `str()` in 2.x
Комментарии:
1. Упс, код будет довольно загадочным. Не можем ли мы найти решение, которое будет работать с hex.
2. Вы пробовали код на Python3?
binascii.unhexlify(x)
даетTypeError: 'str' does not support the buffer interface
3. Я не понимаю, что должна делать часть base64. Вы можете удалить ее, и она все равно будет работать.
4. @sorin: странно… здесь он отлично работает
Python 3.1 (r31:73572, Jul 5 2010, 13:15:03)
. Возможноx.encode("latin1")
, здесь тоже работает лучше…5. @Lennart Regebro Предполагается, что это альтернатива, поскольку предпочтительнее использовать hex.
b'x80xff'
кодируется'gP8='
в base64 и'80FF'
в hex.