Con l'arrivo di Python 3, il tipo bytes è diventato principale per la memorizzazione e l'elaborazione dei dati binari, separandosi dalle stringhe (str). In Python 2, le stringhe (str) potevano contenere sia testo che byte, il che causava frequenti errori nella gestione dei dati in diverse codifiche.
Nella programmazione quotidiana ci troviamo spesso di fronte a compiti di trasferimento e memorizzazione di dati al di fuori del contesto delle informazioni testuali — ad esempio, lavorando con file, richieste di rete e protocolli di scambio. Per questo è richiesto un tipo chiaro, conveniente e sicuro che distingua nettamente la sequenza di byte dai dati stringa.
Il tipo bytes in Python memorizza una sequenza immutabile di byte (numeri interi da 0 a 255) e può essere creato da un letterale di byte (con il prefisso b) o tramite una conversione esplicita dei tipi. Per un'interazione sicura e prevedibile tra stringhe (str) e byte (bytes), si utilizzano i metodi .encode() e .decode(). Quando si lavora con file, reti e vari protocolli binari, bytes è la scelta principale.
Esempio di codice:
# Creazione di un oggetto bytes b = b'hello' # Tramite letterale b2 = bytes([104, 101, 108, 108, 111]) # Da una lista di interi # Conversione str <=> bytes text = 'testo' bin_text = text.encode('utf-8') # str -> bytes back = bin_text.decode('utf-8') # bytes -> str # Esempio con file with open('file.bin', 'rb') as f: data = f.read() # data: bytes
Caratteristiche chiave:
Si possono concatenare bytes e str in una variabile?
No, la concatenazione tramite + o le f-string non funzionano: se si tenta di eseguire b'abc' + 'def', si genera un TypeError. È necessario convertire esplicitamente i tipi.
In che cosa differisce bytes da bytearray?
bytes è un tipo immutabile, il che significa che il contenuto non può essere modificato dopo la creazione. bytearray è una variante modificabile, supporta metodi per cambiare i byte sul posto.
b = bytes([1, 2, 3]) # immutabile ba = bytearray([1, 2, 3]) # modificabile ba[0] = 99 # OK b[0] = 99 # TypeError
Come si può sapere quanti byte occuperà una stringa durante la conversione tramite encode()?
Il numero di byte dipende dalla codifica. Ad esempio, per 'abc' in utf-8 sono 3 byte, mentre 'Ciao' — 12. Solo dopo aver chiamato encode() si può conoscere la dimensione esatta tramite len():
s = 'Ciao' # 4 lettere b = s.encode('utf-8') # 12 byte print(len(b)) # 12
Un sviluppatore legge un file in modalità 'rb' (bytes) e cerca di elaborarlo immediatamente come una stringa:
with open('file.txt', 'rb') as f: for line in f: print(line.strip()) # line: bytes
Pro:
Contro:
Un sviluppatore elabora flussi di byte tramite decode(), introducendo il controllo della codifica:
with open('file.txt', 'rb') as f: for line in f: print(line.decode('utf-8').strip())
Pro:
Contro: