ProgrammationDéveloppeur Backend

Expliquez le fonctionnement et les caractéristiques du type incorporé bytes en Python. Comment et où est-il utilisé, quelles sont les différences par rapport à str, et quelles subtilités sont importantes lors du traitement des données binaires ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question

Avec l'apparition de Python 3, le type bytes est devenu le principal moyen de stocker et de traiter des données binaires, se séparant des chaînes (str). Dans Python 2, les chaînes (str) pouvaient contenir à la fois du texte et des octets, ce qui était à l'origine de nombreuses erreurs lors du traitement des données dans différents encodages.

Problème

Dans la programmation quotidienne, nous sommes souvent confrontés à des tâches de transmission et de stockage de données en dehors du contexte d'informations textuelles — par exemple, le travail avec des fichiers, des requêtes réseau et des protocoles d'échange. Pour cela, un type explicite, pratique et sécurisé est requis, qui différencie clairement une séquence d'octets des données textuelles.

Solution

Le type bytes en Python stocke une séquence d'octets (entiers de 0 à 255) immuable et peut être créé à partir d'un littéral d'octets (avec le préfixe b) ou par conversion explicite des types. Pour une interaction sûre et prévisible entre les chaînes (str) et les octets (bytes), les méthodes .encode() et .decode() sont utilisées. Lorsqu'on travaille avec des fichiers, des réseaux et divers protocoles binaires, bytes est le choix principal.

Exemple de code :

# Création d'un objet bytes b = b'hello' # Via un littéral b2 = bytes([104, 101, 108, 108, 111]) # À partir d'une liste d'entiers # Conversion str <=> bytes text = 'текст' bin_text = text.encode('utf-8') # str -> bytes back = bin_text.decode('utf-8') # bytes -> str # Exemple avec un fichier with open('file.bin', 'rb') as f: data = f.read() # data: bytes

Caractéristiques clés :

  • bytes est un conteneur immuable (immutable) pour une séquence d'octets.
  • Diffère de str : str stocke du texte (Unicode), bytes des données binaires.
  • Toutes les opérations de conversion nécessitent une indication explicite de l'encodage.

Questions piégeuses.

Est-il possible de concaténer bytes et str dans une seule variable ?

Non, la concaténation par + ou les f-strings ne fonctionnent pas : si vous essayez d'exécuter b'abc' + 'def', une TypeError se produira. Il faut convertir explicitement les types.

Quelle est la différence entre bytes et bytearray ?

bytes est un type immuable, c'est-à-dire que le contenu ne peut pas être modifié après sa création. bytearray est une version mutable, supportant des méthodes de modification des octets sur place.

b = bytes([1, 2, 3]) # immutable ba = bytearray([1, 2, 3]) # mutable ba[0] = 99 # OK b[0] = 99 # TypeError

Comment savoir combien de bytes prendra une chaîne lors de la conversion par encode() ?

Le nombre d'octets dépend de l'encodage. Par exemple, pour 'abc' en utf-8, cela représente 3 octets, tandis que 'Привет' — 12. Ce n'est qu'après l'appel à encode() que l'on peut connaître la taille exacte via len() :

s = 'Привет' # 6 lettres b = s.encode('utf-8') # 12 octets print(len(b)) # 12

Erreurs typiques et anti-modèles

  • Confondre bytes et str, passer une chaîne là où des octets sont attendus (par exemple, requêtes HTTP, fichiers binaires), ou vice versa.
  • Oublier de décoder explicitement les octets lors de l'écriture dans un fichier texte ou de l'affichage.
  • Comparer bytes et str directement — toujours False.

Exemple de la vie réelle

Cas négatif

Un développeur lit un fichier en mode 'rb' (octets) et essaie de le traiter immédiatement comme une chaîne :

with open('file.txt', 'rb') as f: for line in f: print(line.strip()) # line: bytes

Avantages :

  • Peut fonctionner pour les documents ASCII.

Inconvénients :

  • Impossible de traiter les fichiers Unicode sans décryptage via decode().
  • Des erreurs surviennent lors de tentatives de concaténation avec str.

Cas positif

Un développeur traite des flux octets via decode(), introduisant un contrôle d'encodage :

with open('file.txt', 'rb') as f: for line in f: print(line.decode('utf-8').strip())

Avantages :

  • Le code fonctionne pour n'importe quel fichier texte dans un encodage correct.
  • Comportement prévisible lors du traitement et de l'affichage.

Inconvénients :

  • Une responsabilité supplémentaire est introduite pour le choix explicite de l'encodage.
  • Une gestion supplémentaire des erreurs est nécessaire en cas de mauvaise décodage.