Преобразование int в байты в Python 3

Я пытался создать этот байтовый объект в Python 3:

b'3\r\n'

поэтому я попробовал очевидное (для меня) и нашел странное поведение:

 >>> bytes(3) + b'\r\n' b'\x00\x00\x00\r\n' 

По всей видимости:

 >>> bytes(10) b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 

Я не мог видеть никаких указателей на то, почему преобразование байтов работает таким образом, считывая документацию. Однако в этой проблеме Python я обнаружил некоторые неожиданные сообщения о добавлении format в байты (см. Также форматирование Python 3 байта ):

http://bugs.python.org/issue3982

Это еще хуже связано с такими странностями, как bytes (int), возвращающими нули сейчас

а также:

Мне было бы гораздо удобнее, если бы байты (int) вернули ASCII-идентификацию этого int; но, честно говоря, даже ошибка была бы лучше, чем такое поведение. (Если бы я хотел этого поведения, чего у меня никогда не было, я бы предпочел, чтобы это был метод класса, вызываемый как «bytes.zeroes (n)».)

Может ли кто-нибудь объяснить мне, откуда такое поведение?

9 Solutions collect form web for “Преобразование int в байты в Python 3”

Так оно и было спроектировано – и это имеет смысл, потому что обычно вы вызываете bytes на итерабельном вместо одного целого:

 >>> bytes([3]) b'\x03' 

Документы указывают это , а также docstring для bytes :

  >>> help(bytes) ... bytes(int) -> bytes object of size given by the parameter initialized with null bytes 

Из python 3.2 вы можете сделать

 >>> (1024).to_bytes(2, byteorder='big') b'\x04\x00' 

https://docs.python.org/3/library/stdtypes.html#int.to_bytes

 def int_to_bytes(x): return x.to_bytes((x.bit_length() + 7) // 8, 'big') def int_from_bytes(xbytes): return int.from_bytes(xbytes, 'big') 

Соответственно, x == int_from_bytes(int_to_bytes(x)) .

Вы можете использовать пакет struct :

 In [11]: struct.pack(">I", 1) Out[11]: '\x00\x00\x00\x01' 

«>» – это байтовый порядок (big-endian), а «I» – символ формата . Поэтому вы можете быть конкретным, если хотите сделать что-то еще:

 In [12]: struct.pack("<H", 1) Out[12]: '\x01\x00' In [13]: struct.pack("B", 1) Out[13]: '\x01' 

Это работает одинаково как на python 2, так и на python 3 .

Примечание: обратная операция (байты в int) может быть выполнена с помощью распаковки .

В документации говорится:

 bytes(int) -> bytes object of size given by the parameter initialized with null bytes 

Последовательность:

 b'3\r\n' 

Это символ «3» (десятичный 51) символ «\ r» (13) и «\ n» (10).

Таким образом, способ будет рассматривать его как таковой, например:

 >>> bytes([51, 13, 10]) b'3\r\n' >>> bytes('3', 'utf8') + b'\r\n' b'3\r\n' >>> n = 3 >>> bytes(str(n), 'ascii') + b'\r\n' b'3\r\n' 

Протестировано на IPython 1.1.0 и Python 3.2.3

Python 3.5+ вводит% -interpolation (форматирование printf style) для байтов :

 >>> b'%d\r\n' % 3 b'3\r\n' 

См. PEP 0461 – Добавление% форматирования в байты и bytearray .

В более ранних версиях вы можете использовать str и .encode('ascii') результат:

 >>> s = '%d\r\n' % 3 >>> s.encode('ascii') b'3\r\n' 

Примечание. Это отличается от того, что производит int.to_bytes :

 >>> n = 3 >>> n.to_bytes((n.bit_length() + 7) // 8, 'big') or b'\0' b'\x03' >>> b'3' == b'\x33' != '\x03' True 

ASCIIfication 3 – это "\x33" не "\x03" !

Это то, что делает python для str(3) но это было бы совершенно неправильно для байтов, поскольку они должны рассматриваться как массивы двоичных данных и не подвергаться злоупотреблениям как строки.

Самый простой способ добиться того, что вы хотите, это bytes((3,)) , который лучше, чем bytes([3]) поскольку инициализация списка намного дороже, поэтому никогда не используйте списки, когда вы можете использовать кортежи. Вы можете преобразовать большие целые числа, используя int.to_bytes(3, "little") .

Инициализация байтов с заданной длиной имеет смысл и является наиболее полезной, поскольку они часто используются для создания некоторого типа буфера, для которого вам нужна некоторая память выделенного размера. Я часто использую это при инициализации массивов или расширении некоторого файла путем написания нулей.

Поведение происходит из-за того, что в Python до версии 3 bytes были просто псевдонимом для str . В bytes Python3.x есть неизменяемая версия bytearray – совершенно новый тип, а не обратно совместимый.

Из байтов docs :

Соответственно, аргументы конструктора интерпретируются как для bytearray ().

Затем, из bytearray docs :

Необязательный параметр источника может использоваться для инициализации массива несколькими способами:

  • Если это целое число, массив будет иметь этот размер и будет инициализирован нулевыми байтами.

Обратите внимание, что это отличается от поведения 2.x (где x> = 6), где bytes просто str :

 >>> bytes is str True 

PEP 3112 :

2.6 str отличается от типа байтов 3.0 различными способами; в частности, конструктор совершенно другой.

int (включая Python2 long ) можно преобразовать в bytes используя следующую функцию:

 import codecs def int2bytes(i): hex_value = '{0:x}'.format(i) # make length of hex_value a multiple of two hex_value = '0' * (len(hex_value) % 2) + hex_value return codecs.decode(hex_value, 'hex_codec') 

Обратное преобразование можно сделать другим:

 import codecs import six # should be installed via 'pip install six' long = six.integer_types[-1] def bytes2int(b): return long(codecs.encode(b, 'hex_codec'), 16) 

Обе функции работают как на Python2, так и на Python3.

  • Могу ли я сделать pprint в python3 не разбивать строки, как в python2?
  • использование locals () внутри понимания словаря
  • Не можете понять, как печатать по горизонтали в python?
  • Прозрачное взаимодействие с консолью (sh, bash, cmd, powershell)
  • изменение в обработке импорта / модулей от python2 до python3?
  • Запись в новый файл, если он не существует, и добавление к файлу, если оно
  • Как запустить python для windows?
  • Итерация по элементам словаря (), значениям (), keys () в Python 3
  • Почему неклассическое ключевое слово Python, как глобальная область видимости?
  • Скребок: как переформатировать сбор и вывод данных csv
  • python random.setstate (), seed () - есть ли гарантия одинаковых результатов в реализациях?
  •  
    Interesting Posts for Van-Lav

    Python AppIndicator bindings -> howto проверить, открыто ли меню?

    Извлечение части данных из файла JSON с помощью python

    Что делает наборы быстрее, чем списки в python?

    Как бы я ввел строки пути файла в список, основываясь на соответствующих путях папок в Python

    Вычисление парной корреляции между всеми столбцами

    Как выводить график из Matplotlib в шаблонах Django?

    urllib.request для python 3.3 не работает для загрузки файла

    Как программно получить контрольную сумму MD5 файла Amazon S3 с помощью boto

    Лучший способ получить максимальное значение в столбце Dataframe Spark

    Поддержка pyqt jpeg не работает в комплекте

    Как проверить, находится ли задача уже в очереди python?

    Рамка роботов: использование фейкера для создания префиксной строки для данных учетной записи

    Slice 2d массив в меньшие 2d массивы

    поддерживаемые pydoc метаданные python, такие как __version__ = '0,1'

    Ошибка компиляции кода C для пакета python hmmlearn

    Python - лучший язык программирования в мире.