Типы bytes и bytearray в python
https://t.me/learnpythonforfun (Denis Obrezkov)Мотивация
Python часто используется для различных манипуляций с данными, типичный пример работы: считать данные от пользователя, запаковать их в запрос, отправить данные на сервер. Иногда такие запакованные данные предстают не в виде текста, а в виде последовательностей нулей и единиц, с которыми, однако, программисту надо как-то работать. В таких случаях выручают объекты bytes и bytearray.
О байтах и битах
Биты и байты считаются единицами измерения информации. Двоичный бит принимает два значения: ноль и единица. Используя бит мы можем закодировать только два состояния, но если мы используем два бита подряд, то таких состояний уже будет четыре: 00, 01, 10, 11. Мы можем даже закодировать маленький алфавит: А - 00, Б - 01, В - 10, Г - 11. Эти двоичные последовательности, также соответствуют двоичным представлениям чисел 0, 1, 2, 3.
Байт — это единица измерения информации, в типичном современном компьютере состоящая из восьми бит. Вот примеры байтов: 10010101, 00000001, 11111111, 00000000. Эти байты позволяют закодировать числа от 0 до 255. Соответственно, они позволяют закодировать даже весь алфавит. Так, к примеру, и сделано в ASCII таблице, которая использует 7 бит:
Зачем такая кодировка нужна? Если говорить очень грубо, то так как по проводам мы можем передавать только условно низкий (0) и высокий (1) уровни напряжения, то и все передаваемое мы должны кодировать нулями и единицами.
Тип bytes в python
Для работы с последовательностями нулей и единиц, в python есть тип bytes. Он является неизменяемым, а его создание происходит следующим образом:
>>> binary_obj = b'These are some bytes' >>> print(binary_obj) b'This are some bytes'
Обратите внимание, что инициализация отличается от строкового объекта:
>>> string_obj = 'These are some letters' >>> print(string_obj) This are some letters
Типы созданных объектов тоже будут разными:
>>> print(type(binary_obj)) <class 'bytes'> >>> print(type(string_obj)) <class 'str'>
Байтовый объект можно получить и из строки,указав её кодировку:
>>> bytes(string_obj, encoding='utf-8') b'This are some letters'
Кроме этого, байтовый объект можно инициализировать нулями:
>>> bytes(10) b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
перечисляемым набором целых чисел:
>>> bytes(range(16)) b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
или неким бинарным объектом.
Так как объекты byte неизменяемые, то их часто применяют при написании тестов, там, где требуются наперед заданные нетекстовые значения, к примеру, при тестировании криптографических библиотек. Часто же, больший интерес представляет изменяемый аналог byte - bytearray.
Тип bytearray в python
Объекты bytearray являются изменяемой альтернативой объектам bytes. К примеру, если в объекте bytes мы попытаемся на место второго байта подставить байт со значением f (со значением в таблице кодировки 102), то для объекта bytes будет выдана ошибка :
>>> a = b"abc" >>> a[1] = 102 TypeError: 'bytes' object does not support item assignment
а для bytearray ошибки не будет:
>>> b = bytearray('abc', encoding='utf-8') >>> b[1] = 102 >>> b bytearray(b'afc')
Оба класса bytes и bytearray имеют операции обычных последовательностей, такие как: capitalize()
, isdigit()
, split()
, strip()
и т.д. Одной из отличительных особенностей этих типов является тип возвращаемых значений по срезу и по индексу. К примеру, для строки в обоих случаях возвращаемый тип будет строкой:
>>> print(str1[4], type(str1[4])) o <class 'str'> >>> print(str1[4:5], type(str1[4:5])) o <class 'str'>
Для типа байт, обращение по индексу вернет целочисленное значение, соответствующее элементу, а срез - объект типа bytes с тем запрошенным элементом:
>>> print(byte1[4], type(byte1[4])) 111 <class 'int'> >>> print(byte1[4:5], type(byte1[4:5])) b'o' <class 'bytes'>
Заключение
Мы рассмотрели классы bytes
и bytearray
. Эти классы позволяют работать с байтовыми представлениями данных, при этом первый является неизменяемым, а второй является изменяемым аналогом первого. Оба этих типа часто используются при тестировании программ, там где нужно подать сырые данные на вход программе, к примеру, в ручную сформированный “сломанный” пакет данных или криптографический ключ, обладающий необходимыми свойствами.