Тип данных bytes
- это неизменяемые последовательности отдельных байтов. Основные двоичные протоколы основаны на кодировании текста ASCII
.
Синтаксис для байтовых литералов в основном такой же, как и для строковых литералов, за исключением того, что добавляется префикс 'b'
:
Как и в случае строковых литералов, байтовые литералы могут также использовать префикс '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]