Новые типы двоичных последовательностей во многих отношениях похожи на тип str в Python 2. Главное что нужно знать – это то, что существуют два основных встроенных типа двоичных последовательностей: неизменяемый тип bytes, появившийся в Python 3, и изменяемый тип bytearray, добавленный в Python 2.6.
Кстати, в Python 2.6 был также введен тип bytes, но лишь как псевдоним типа str, он ведет себя иначе, чем тип bytes в Python 3.
Каждый элемент bytes или bytearray – целое число от 0 до 255, а не односимвольная строка, как в типе str в Python 2 str.
Однако срез двоичной последовательности всегда является двоичной последовательностью того же типа, даже если это срез длины.
Пример №1. Пятибайтовая последовательность в виде bytes и bytearray.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> cafe = bytes('café', encoding="utf_8") # (1) >>> cafe b'caf\xc3\xa9' >>> cafe[0] # (2) 99 >>> cafe[:1] # (3) b'c' >>> cafe_arr = bytearray(cafe) >>> cafe_arr # (4) bytearray(b'caf\xc3\xa9') >>> cafe_arr[-1:] # (5) bytearray(b'\xa9') >>> |
1. bytes можно получить из str, если известна кодировка.
2. Каждый элемент – целое число в диапазоне range(256).
3. Срезы bytes также имеют тип bytes, даже если срез состоит из одного байта
4. Для типа bytearray не существует литерального синтаксиса: в оболочке объекты этого типа представляются в виде конструктора bytearray(), аргументом которого является литерал типа bytes.
5. Срез cafe_arr также имеет типа bytearray
Тот факт, что my_bytes[0] возвращает int, а my_bytes[:1] – объект bytes длины 1, не должен вызывать удивления. Единственный тип последовательности, для которого s[0] == s[:1] – это типа str.
И хотя на практике этот тип используется сплошь и рядом, его поведение – исключение из правила. Для всех остальных последовательностей s[i] возвращает один элемент, а s[i:i+1] – последовательность, состоящую из единственного элемента s[i].
Хотя двоичные последовательности – на самом деле, последовательности целых чисел, в их литеральной нотации отражен тот факт, что часто они включают ASCII-текст.
Поэтому применяются различные способы отображения, зависящие от значения каждого байта.
- Для байтов из диапазона символов ASCII, имеющих графическое начертание – от пробела до ~ выводится сам символ ASCII.
- Для байтов, соответствующих символам табуляции, новой строки, возврата каретки и \, выводятся управляющие последовательности \t, \n, \r и \\.
- Для все остальных байтов выводится шестнадцатеричное представление, например, нулевой байт представляется последовательностью \x00.
Именно поэтому в примере №1 мы видим представление b’caf\xc3\xa9′. Первые три байта b’caf’ принадлежат диапазону символов ASCII с графическим начертанием, последний – нет.
Оба типа bytes и bytearray поддерживают все методы типа str кроме тех, что относятся к форматированию(format, format_map), и еще нескольких, прямо зависящих от особенностей Unicode, в том числе casefold, isdecimal, isidentifier, isnumeric, isprintable и encode.
Это означает, что при работе с двоичными последовательностями мы можем пользоваться знакомыми методами строк, например endswith, replace, strip, translate, upper и десятками других, только аргументы должны иметь тип bytes, а не str.
К двоичным последовательностям применимы и функции для работы с регулярными выражениями из модуля re, если регулярное выражение откомпилировано из двоичной последовательности, а не из str.
Оператор % не работает с двоичными последовательностями в версиях от Python 3.0 до 3.4, но, если верить документу PEP 461, то его предполагается поддержать в будущем.
Оператор % часто используется во многих языках программирования. Один мой знакомый который разрабатывает шаблоны для WordPress как например ThemeForest Grand Conference рассказал что без оператора % пришлось бы изобретать велосипеды каждый день.
Для двоичных последовательностей существует метод класса, отсутствующий в типе str: fromhex, который строит последовательность, разбирая пары шеснадцатеричных цифр, которые могут быть разделены пробелами, хотя это и не обязательно.
1 2 3 |
>>> bytes.fromhex("34 FF FA A3 A5") b'4\xff\xfa\xa3\xa5' >>> |
Другие способы построения объектов bytes и bytearray связаны с вызовом различных конструкторов:
- с именованными аргументами str и encoding;
- с итерируемым объектом, порождающим элементы со значениями от 0 до 255;
- с объектом который реализует протокол буфера (например, bytes, bytearray, memoryview, array.array), при этом байты копируются из исходного объекта во вновь созданную двоичную последовательность.
Построение двоичной последовательности из буфероподобного объекта – это низкоуровневая операция, которая может потребовать приведения типов.
Пример №2. Инициализация байтов данными, хранящимися в массиве.
1 2 3 4 5 6 |
>>> import array >>> numbers = array.array('h', [-3, -2, -1, 0, 1, 2, 3]) # (1) >>> octets = bytes(numbers) # (2) >>> octets b'\xfd\xff\xfe\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00' # (3) >>> |
1. Код типа ‘h’ означает создание массива коротких целых (16-разрядных).
2. В объекте octets хранится копия байтов, из которых составлены числа в массиве numbers.
3. Это четырнадцать байтов, представляющих семь коротких целых чисел.
Зачем нужны боты в группе ВК? Почему иногда они лучше, чем люди? Портал https://pricesmm.com/ ответил на каверзные вопросы и выяснил, как накрутить ботов Вконтакте за деньги и без затрат. Для вас полный и честный обзор всех доступных способов, а также условия и секреты, чтобы обезопасить процесс.
Создание объекта bytes или bytearray из буфероподобного источника всегда сопровождается копированием байтов.
Напротив, объекты типа memoryview позволяют разным двоичным структурам данных использовать одну и ту же область памяти.
Для извлечения структурированной информации из двоичной последовательности бесценную пользу может оказать модуль struct.