Работа с байтами: префикс b в Python 3

Раздел: Основы Python -> Работа со строками и байтами

Префикс b для строк в Python 3

Как создать байтовый литерал из ASCII символов?

Простейший способ получить объект bytes в Python 3 - использовать префикс b перед строковым литералом, заключенным в кавычки. Например:

data = b'hello'
print(data)      # b'hello'
print(type(data)) # <class 'bytes'>
print(len(data)) # 5

использование b в python (использование префикса b в python)

Каждый символ внутри литерала b'...' интерпретируется как ASCII-код и занимает ровно один байт. Такой литерал может содержать цифры, латинские буквы, знаки препинания и некоторые escape-последовательности (\n, \x, \t и т.д.).

Типичная ошибка: попытка поместить в b'...' символы, не входящие в диапазон ASCII (например, кириллица). Это приведет к SyntaxError:

# b'привет'  # SyntaxError: bytes can only contain ASCII literal characters.

Str b a в python 3 (префикс b для строк в python 3)

Решение: использовать кодирование обычной строки (см. варианты ниже).

Цель: быстрое создание байтовых данных для низкоуровневых операций - работа с сетевыми протоколами, бинарными файлами, криптографией.

Вариант 1: Преобразование строки через encode()

Как преобразовать обычную строку (str) в байты с явным указанием кодировки?

Метод encode() вызывается у строки и возвращает объект bytes. Кодировку нужно задавать вторым аргументом (по умолчанию utf-8).

text = "Привет, мир!"
data = text.encode('utf-8')
print(data)  # b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82, \xd0\xbc\xd0\xb8\xd1\x80!'
print(len(data))  # 19 (каждый русский символ занимает 2 байта в UTF-8)

Python b string (строки с префиксом b в python)

Такой способ подходит для любых символов, в том числе Unicode. Важно помнить: при декодировании нужно использовать ту же кодировку.

Типичная ошибка: использование encode() без указания кодировки, когда байты потом читаются с другой кодировкой. Это приводит к UnicodeDecodeError или искажению.

# Кодирование в utf-8, а декодирование в cp1251
original = "Привет"
encoded = original.encode('utf-8')
try:
    decoded = encoded.decode('cp1251')
except UnicodeDecodeError as e:
    print(f"Ошибка: {e}")

Python b format (формат b в python)

Ошибка: 'charmap' codec can't decode byte 0x9f in position 0: character maps to <undefined>

Решение: всегда передавать кодировку явно и согласовывать её на всех этапах.

Вариант 2: Конструктор bytes()

Каким образом создать объект bytes из строки или последовательности чисел?

Конструктор bytes() может принимать строку с указанием кодировки, итератор целых чисел (0-255), число (создаст нулевые байты) или байтоподобный объект.

# Из строки
b1 = bytes("abc", "ascii")
print(b1)   # b'abc'

# Из списка чисел (коды символов)
b2 = bytes([97, 98, 99])
print(b2)   # b'abc'

# Из целого числа (создает последовательность нулевых байтов)
b3 = bytes(5)
print(b3)   # b'\x00\x00\x00\x00\x00'

Конструктор удобен для создания байтов из явно заданных значений, например, для формирования бинарных заголовков.

Типичная ошибка: передача строки без кодировки - получим TypeError.

# bytes("abc")  # TypeError: string argument without an encoding

Решение: всегда указывать кодировку вторым аргументом.

Вариант 3: Экранирование hex в префиксе b

Как записать байты с произвольными значениями, не все из которых соответствуют читаемым символам?

Внутри b'...' можно использовать escape-последовательность \xHH, где HH - шестнадцатеричный код байта.

data = b'\x48\x65\x6c\x6c\x6f'  # H e l l o
print(data.decode('ascii'))  # Hello

Также доступны другие escape-последовательности: \n (новая строка, байт 0x0A), \t (табуляция, 0x09), \\ (обратная косая черта).

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

Вариант 4: Изменяемые байты - bytearray

Как создать изменяемую последовательность байтов, чтобы модифицировать её после создания?

Тип bytearray похож на bytes, но элементы можно изменять. Создаётся так же: через префикс ba (не путать!), литерала с префиксом ba нет; используется конструктор bytearray(b'...') или bytearray(5).

ba = bytearray(b'Hello')
print(ba[0])  # 72 (код 'H')
ba[0] = 104   # меняем на 'h'
print(ba)     # bytearray(b'hello')

# Преобразование обратно в bytes
b = bytes(ba)
print(b)      # b'hello'

Используется, когда нужна изменяемая память - например, при построении пакета данных по частям.

Расширенные примеры работы с префиксом b и байтами

Пример 1. Комбинирование escape-последовательностей

Пример
data = b'Line1\nLine2\tTabbed\x00Null'
print(data)
print('As list:', list(data))
b'Line1\nLine2\tTabbed\x00Null'
As list: [76, 105, 110, 101, 49, 10, 76, 105, 110, 101, 50, 9, 84, 97, 98, 98, 101, 100, 0, 78, 117, 108, 108]

Пример 2. Преобразование строки в байты с разными кодировками

Пример
text = "Python 3 работает с Unicode"
utf8 = text.encode('utf-8')
cp1251 = text.encode('cp1251')
print('UTF-8:', utf8)
print('CP1251:', cp1251)
print('Длина UTF-8:', len(utf8))
print('Длина CP1251:', len(cp1251))
UTF-8: b'Python 3 \xd1\x80\xd0\xb0\xd0\xb1\xd0\xbe\xd1\x82\xd0\xb0\xd0\xb5\xd1\x82 \xd1\x81 Unicode'
CP1251: b'Python 3 \xf0\xe0\xe1\xee\xf2\xe0\xe5\xf2 \xf1 Unicode'
Длина UTF-8: 27
Длина CP1251: 22

Пример 3. Чтение и запись в бинарный файл

Пример
# Запись байтов в файл
with open('data.bin', 'wb') as f:
    f.write(b'\x00\x01\x02\xff')

# Чтение обратно
with open('data.bin', 'rb') as f:
    content = f.read()
    print('Прочитано:', content)
    print('В виде чисел:', list(content))
Прочитано: b'\x00\x01\x02\xff'
В виде чисел: [0, 1, 2, 255]

Пример 4. Отправка и получение байтов через сокет (упрощённо)

Пример
import socket

# Серверная часть (для демонстрации)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65432))
server.listen(1)
# Клиентская часть (в реальном коде в разных потоках)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65432))

conn, addr = server.accept()
# Отправка байтов сервером
conn.sendall(b'Hello from server')
# Приём клиентом
data = client.recv(1024)
print('Клиент получил:', data)

conn.close()
server.close()
client.close()
Клиент получил: b'Hello from server'

Пример 5. Обработка ошибок декодирования с разными стратегиями

Пример
broken = b'\xff\xfe\x00'  # некорректная UTF-8
print('strict:', end=' ')
try:
    broken.decode('utf-8')
except UnicodeDecodeError as e:
    print(e)

print('ignore:', broken.decode('utf-8', errors='ignore'))
print('replace:', broken.decode('utf-8', errors='replace'))
print('backslashreplace:', broken.decode('utf-8', errors='backslashreplace'))
strict: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
ignore: 
replace: ���
backslashreplace: \xff\xfe\x00

Пример 6. Срезы и конкатенация байтов

Пример
b1 = b'Hello'
b2 = b' World'
b3 = b1 + b2
print('Конкатенация:', b3)
print('Срез [1:4]:', b3[1:4])
print('Поиск подстроки:', b'World' in b3)
Конкатенация: b'Hello World'
Срез [1:4]: b'ell'
Поиск подстроки: True

Пример 7. Bytes как последовательность целых

Пример
data = b'\x41\x42\x43'
for byte in data:
    print(byte, end=' ')
print()
# Список целых
print(list(data))  # [65, 66, 67]
65 66 67 
[65, 66, 67]

Пример 8. Использование bytearray для модификации

Пример
ba = bytearray(b'\x00\x01\x02\x03')
print('До:', ba)
ba[1] = 0xff
print('После:', ba)
# Добавление нового элемента (расширение)
ba.append(10)
print('После append:', ba)
# Удаление по индексу
del ba[0]
print('После удаления первого:', ba)
До: bytearray(b'\x00\x01\x02\x03')
После: bytearray(b'\x00\xff\x02\x03')
После append: bytearray(b'\x00\xff\x02\x03\n')
После удаления первого: bytearray(b'\xff\x02\x03\n')

Префикс b для строк в Python 3 - comments

En
Str b a в python 3 (python)