Перейти до змісту

Послідовності бінарних даних

Основні вбудовані класи для роботи з послідовностями бінарних даних в Python — це bytes і bytearray.

bytes

Байти — немутабельна послідовність окремих байт (чисел у діапазоні від 0 до 255).

Оскільки більшість основних бінарних протоколів базуються на кодуванні тексту ASCII, об'єкти байтів працюють з ASCII-сумісними символами і це нагадує роботу з символьними рядками. Синтаксис для літералів байтів в значній мірі такий же, як і для літералів символьного рядка, за винятком того, що додається префікс b:

>>> b = b'Hi there!'
>>> b
b'Hi there!'
>>>

Допускаються лише ASCII-символи, тобто значення до 127 включно:

>>> b = b'Привіт!'
  File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>>

Інші значення задаються у шістнадцятковій системі числення, до значення додається префікс \x:

>>> b = b'\x00\xff'
>>> b
b'\x00\xff'
>>> b[0]
0
>>> b[1]
255
>>>

"Сирі" байти (аналогічно "сирим" рядкам) теж допускаються:

>>> b = rb'\n'
>>> b
b'\\n'
>>>

Створити байтову послідовність можна за допомогою конструктора класа вказавши її довжину, при цьому створена послідовність буде заповнена значенням 0:

>>> b = bytes(5)
>>> b
b'\x00\x00\x00\x00\x00'
>>>

Також можна передати конструктору ітерабельний об'єкт цілих чисел:

>>> b = bytes(range(5))
>>> b
b'\x00\x01\x02\x03\x04'
>>>

Можна створити послідовність байт з символьного рядка, для цього треба вказати кодування, в якому ми хочемо отримати наш рядок:

>>> b = bytes('ї', encoding='UTF-8')
>>> b
b'\xd1\x97'
>>>

Клас bytes має метод fromhex() який дозволяє створити об'єкт з символьного рядка. Рядок повинен складатись з пар шістнадцяткових цифр, пробіли ігноруються:

>>> bytes.fromhex('41f0 F1f2  ')
b'A\xf0\xf1\xf2'
>>>

Є також метод який виконує "зворотню дію" — повертає шістнадцяткове представленя байтового об'єкта як символьний рядок:

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

Ще один важливий метод класа bytes:

 decode(encoding="utf-8", errors="strict")

Метод декодує послідовність байт з вказаного кодування у символьний рядок:

>>> b = b'\xd0\x92\xd1\x96\xd1\x82\xd0\xb0\xd1\x8e!'
>>> b.decode()
'Вітаю!'
>>>

Другий параметр цього метода вказує, що робити якщо під час декодування відбувається помилка. Значення за замовчуванням strict означає, що у разі виникнення помилки буде піднято виняток UnicodeError. Також за допомогою цього параметра можна вказати, що усі помилки декодування будуть ігноруватись, замінятись на певний символ, інше (докладніше — читайте у документації Python).

Як ви могли вже зауважити, в залежності від значення кожного байта застосовуються різні способи відображення:

  • для байтів з діапазона символів ASCII, які мають графічне відображення — від пробіла до ~ — выводится сам символ ASCII.
  • для байтів, які відповідають символам табуляції, нового рядка, бекслеш та інших виводяться відповідні ескейп-послідовності.
  • для решти байтів виводиться шістнадцяткове представлення, наприклад \x00.

bytes підтримує усі методи str крім тих, що стосуються форматування (format, format_map), і ще декількох, які напряму залежать від особливостей Unicode, у тому числі casefold, isdecimal, isidentifier, isnumeric, isprintable і encode. Це означає, що при работі з бінарними послідовностями ми можемо користуватись знайомими методами символьних рядків, наприклад endswith, replace, strip, upper і десятками інших, тільки аргументи мають бути типу bytes, а не str.

bytearray

Масив байтів — мутабельна послідовність окремих байт (чисел у діапазоні від 0 до 255).

Головна відмінність масива байтів від байт — це те, що перша є мутабельною послідовністю. Отже ми можемо використовувати усі методи, які властиві мутабельним послідовностям:

>>> b = bytearray(3)
>>> b.insert(0,65)
>>> b
bytearray(b'A\x00\x00\x00')
>>> b.append(65)
>>> b
bytearray(b'A\x00\x00\x00A')
>>> b.pop()
65
>>> b
bytearray(b'A\x00\x00\x00')
>>> b.reverse()
>>> b
bytearray(b'\x00\x00\x00A')
>>> b.remove(65)
>>> b
bytearray(b'\x00\x00\x00')
>>>

Додаткові матеріали:

Python docs: послідовності бінарних даних

Back to top