Байтовые литералы с префиксом b в Python
Основы работы с префиксом b в Python
Префикс b в Python используется для создания байтовых литералов, то есть последовательностей байтов (тип bytes). Такие литералы записываются как обычная строка, но с префиксом b перед кавычками: b'text'. В отличие от строк str, которые представляют Unicode символы, байтовые литералы представляют необработанные байты (значения от 0 до 255).
Наиболее эффективный способ работы с байтовыми константами – использовать префикс b. Он позволяет создать байтовую строку без вызова функции bytes() и указывает интерпретатору, что данные являются байтами, а не текстом. Это особенно полезно для представления бинарных протоколов, файловых заголовков и криптографических ключей.
b'hello'использование b в python (использование префикса b в python)
b'hello'
Str b a в python 3 (префикс b для строк в python 3)
Как получить байтовое представление строки в определённой кодировке?
Для этого используется метод str.encode().
text = "Привет, мир!"
encoded = text.encode('utf-8')
print(encoded)
Python b string (строки с префиксом b в python)
b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82, \xd0\xbc\xd0\xb8\xd1\x80!'
Python b format (формат b в python)
Аргумент кодировки может быть любым поддерживаемым: 'utf-8', 'cp1251', 'latin-1' и т.д.
Возможные проблемы: Если строка содержит символы, не представимые в выбранной кодировке, возникает UnicodeEncodeError. Решение: указать параметр errors, например errors='ignore' (пропустить) или errors='replace' (заменить на ?).
text = "Français"
encoded = text.encode('ascii', errors='replace')
print(encoded) # b'Fran?ais'Как преобразовать байтовую строку обратно в читаемый текст?
Используется метод bytes.decode().
data = b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82'
decoded = data.decode('utf-8')
print(decoded)Привет
Возможные проблемы: При несовпадении кодировки возникает UnicodeDecodeError. Решение: использовать errors='replace' или 'ignore'.
data = b'\xff\xfe'
decoded = data.decode('utf-8', errors='replace')
print(decoded) # выведет символ заменыКак получить изменяемую последовательность байтов, чтобы модифицировать отдельные элементы?
Класс bytearray создаёт изменяемый массив из байтового литерала или другого итерируемого объекта.
ba = bytearray(b'abcdef')
ba[0] = 120 # 'x'
ba[1:3] = b'yz'
print(ba)bytearray(b'xyzdef')
Возможные проблемы: bytearray не является хэшируемым, поэтому его нельзя использовать как ключ словаря. Для хэширования нужно преобразовать в bytes.
# Ошибка: unhashable type: 'bytearray'
# {bytearray(b'123'): 'value'}Как правильно читать и записывать бинарные данные в файл, не повредив их?
При работе с файлами в бинарном режиме используется флаг 'b' ('rb', 'wb', 'ab'). Данные должны быть байтового типа.
# Запись
with open('data.bin', 'wb') as f:
f.write(b'\x00\x01\x02\x03')
# Чтение
with open('data.bin', 'rb') as f:
content = f.read()
print(content)b'\x00\x01\x02\x03'
Типичная ошибка: попытка записать строку в бинарный файл: TypeError: a bytes-like object is required, not 'str'. Перед записью необходимо закодировать строку.
# Ошибка:
# with open('data.bin', 'wb') as f:
# f.write("text")Можно ли объединить байтовую строку и обычную строку оператором +?
Нельзя. Python строго различает типы bytes и str. Для объединения нужно привести оба операнда к одному типу.
# Ошибка
# result = b'hello' + ' world' # TypeErrorПравильный способ:
result = b'hello' + ' world'.encode()
print(result) # b'hello world'Проблема: Иногда забывают про кодировку, и строка кодируется в utf-8, что может быть нежелательно. Важно явно указывать кодировку.
Как применять регулярные выражения к бинарным данным?
Модуль re поддерживает байтовые шаблоны и байтовые строки. Шаблон также должен быть байтовым.
import re
pattern = b'\\d+'
text = b'abc123def456'
matches = re.findall(pattern, text)
print(matches)[b'123', b'456']
Важно: Символы в байтовом шаблоне соответствуют байтам, а не Unicode символам. Для работы с многобайтовыми кодировками (UTF-8) лучше использовать str и декодировать.
Как закодировать байты в строку base64 для передачи по текстовым протоколам?
Модуль base64 принимает и возвращает байтовые строки.
import base64
original = b'Python bytes'
encoded = base64.b64encode(original)
print(encoded)
decoded = base64.b64decode(encoded)
print(decoded)b'UHl0aG9uIGJ5dGVz' b'Python bytes'
Ошибка: Если передать строку в base64.b64encode, возникнет TypeError. Необходимо убедиться, что входные данные bytes.
Расширенные примеры работы с байтовыми строками
Ниже приведены неочевидные сценарии использования байтовых литералов и методов bytes.
Преобразование целых чисел в байты и обратно
num = 1024
# в 2 байта, big-endian
b = num.to_bytes(2, 'big')
print(b)
# обратно
num_back = int.from_bytes(b, 'big')
print(num_back)b'\x04\x00' 1024
Упаковка и распаковка структурированных данных с помощью struct
import struct
# упаковка: формат '>IH' - big-endian, unsigned int (4 байта) и unsigned short (2 байта)
packed = struct.pack('>IH', 42, 256)
print(packed)
# распаковка
unpacked = struct.unpack('>IH', packed)
print(unpacked)b'\x00\x00\x00\x2a\x01\x00' (42, 256)
Хеширование байтов с помощью hashlib
import hashlib
data = b'secret message'
hash_obj = hashlib.sha256(data)
hex_digest = hash_obj.hexdigest()
print(hex_digest)b'5f0c...' (64 символа)
Исследование заголовка PNG (первые 8 байт)
expected = b'\x89PNG\r\n\x1a\n'
with open('image.png', 'rb') as f:
header = f.read(8)
if header == expected:
print("Это PNG файл")
else:
print("Неизвестный формат")Это PNG файл
Отправка данных через сокет (байты обязательны)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('example.com', 80))
request = b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'
sock.sendall(request)
response = sock.recv(4096)
print(response[:200])b'HTTP/1.1 200 OK\r\n...'
Использование memoryview для эффективного чтения байтов без копирования
data = b'abcdefgh'
mv = memoryview(data)
print(mv.nbytes)
print(mv[2:5].tobytes())8 b'cde'
Преобразование между hex строкой и байтами
h = 'deadbeef'
b = bytes.fromhex(h)
print(b)
b2 = bytes.fromhex('deadbeef') # правильный способb'\xde\xad\xbe\xef'
Фильтрация байтов (оставить только буквы ASCII)
data = b'Hello123World!'
filtered = bytes(filter(lambda x: 65 <= x <= 90 or 97 <= x <= 122, data))
print(filtered)b'HelloWorld'
Использование bytearray для сдвига значений (ROT13 для байтов)
ba = bytearray(b'abcxyz')
for i in range(len(ba)):
if 97 <= ba[i] <= 109:
ba[i] += 13
elif 110 <= ba[i] <= 122:
ba[i] -= 13
print(ba)bytearray(b'nopklm')