Сообщить об ошибке.

Байтовые строки bytes в Python

Тип данных bytes - это неизменяемые последовательности отдельных байтов. Основные двоичные протоколы основаны на кодировании текста ASCII.

Синтаксис для байтовых литералов в основном такой же, как и для строковых литералов, за исключением того, что добавляется префикс 'b':

  • Одинарные кавычки: b'still allows embedded "double" quotes'
  • Двойные кавычки: b"still allows embedded 'single' quotes"
  • Тройные кавычки: b'''3 single quotes'''b"""3 double quotes"""

Как и в случае строковых литералов, байтовые литералы могут также использовать префикс 'r'для отключения обработки escape-последовательностей.

Помимо литеральных форм, объекты bytes могут быть созданы с помощью встроенного класса bytes():

  • Заполненный нулями объект байтов указанной длины: bytes(10).
  • Из итерируемых целых чисел: bytes(range(20)).
  • Копирование существующих двоичных данных через буферный протокол: bytes(obj).

В то время как байтовые литералы основаны на тексте ASCII, байтовые объекты фактически ведут себя как неизменяемые последовательности целых чисел, причем каждое значение в последовательности ограничено таким образом, что 0 <= x < 256, попытки нарушить это ограничение вызовут ValueError. Это сделано специально, чтобы подчеркнуть, что слепое применение алгоритмов обработки текста к двоичным форматам данных, которые не совместимы с ASCII, обычно приводит к повреждению данных.

Для байтовых строк доступны следующие операции:

Две шестнадцатеричные цифры точно соответствуют одному байту, поэтому шестнадцатеричные числа являются широко используемым форматом для описания двоичных данных. Соответственно, тип bytes имеет дополнительный метод класса для чтения данных в этом формате:


bytes.fromhex(string)::

Метод bytes.fromhex() возвращает объект bytes, декодируя данный строковый объект. Строка должна содержать две шестнадцатеричные цифры на байт, при этом пробелы ASCII игнорируются.

>>> bytes.fromhex('2Ef0 F1f2  ')
# b'.\xf0\xf1\xf2'

bytes.hex()::

Метод bytes.hex() преобразовывает объект bytes в его шестнадцатеричное представление. Возвращает строковый объект, содержащий две шестнадцатеричные цифры для каждого байта.

>>> b'\xf0\xf1\xf2'.hex()
# 'f0f1f2'

В Python-3.8 метод bytes.hex() поддерживает необязательные параметры sep и bytes_per_sep для вставки разделителей между байтами в шестнадцатеричный вывод.

Если нужно облегчить чтение шестнадцатеричной строки, можно указать параметр sep разделителя из одного символа для включения в вывод. По умолчанию между каждым байтом. Второй необязательный параметр bytes_per_sep управляет интервалом. Положительные значения вычисляют положение разделителя справа, отрицательные значения слева.

>>> value = b'\xf0\xf1\xf2'
>>> value.hex('-')
# 'f0-f1-f2'
>>> value.hex('_', 2)
# 'f0_f1f2'
>>> b'UUDDLRLRAB'.hex(' ', -4)
#'55554444 4c524c52 4142'

Важно: Поскольку байтовые объекты являются неизменяемыми последовательностями целых чисел (подобно кортежу), то для байтового объекта 'b', b[0] будет целым числом, а b[0:1] - байтовым объектом длины 1. Это контрастирует с текстовыми строками, где индексация и срез будут производить строку длиной 1 символ.

Представление объектов bytes использует литеральный формат (b'...') так как это часто более полезно и наглядно, чем, например, bytes([46, 46, 46]). Вы всегда можете преобразовать объект bytes в список целых чисел с помощью list(b).

Примеры использования:

>>> b = bytes([46, 46, 46])
>>> b
# b'...'
>>> list(b)
# [46, 46, 46]
>>> b = bytes(range(40,60,2))
>>> b
# b'(*,.02468:'
>>> list(b)
[40, 42, 44, 46, 48, 50, 52, 54, 56, 58]