Formation PUB400 : Python, 2018 La syntaxe, les structures de données et les structures de contrôle

3.6 Les chaînes d'octets


Dans certains contextes, Python 3 attend une chaîne d'octets (en anglais : byte object ou byte string) et non une chaîne de caractères.

C'est le cas notamment lorsqu'on code un serveur HTTP de test en définissant une classe dérivée de BaseHTTPRequestHandler. Dans cette classe, les méthodes do_GET() ou do_POST() doivent retourner une chaîne d'octets.

Si elles retournent une chaîne de caractères, vous obtiendrez le message « TypeError: a bytes-like object is required, not 'str' ».

C'est également le cas lorsque le script Python tente d'envoyer des données sur le port série à l'aide de Serial.write(). Cette fois, si vous tentez d'envoyer une chaîne de caractères plutôt qu'une chaîne d'octets, vous obtiendrez le message « unicode strings are not supported, please encode to bytes ».

Chaîne de caractères vs chaîne d'octets

Une chaîne d'octets a ceci de particulier : elle peut être stockée directement sur le disque. C'est qu'elle est composée spécifiquement des caractères dont la valeur ASCII est située entre 32 et 127 inclusivement : caractères non accentués en majuscules ou en minuscules, espaces, chiffres et quelques caractères spéciaux, par exemple !, ", #, $, %, &, ', (, ), *, +, -, /, la virgule et le point.

Quant à la chaîne de caractères, puisqu'elle peut contenir une plus grande diversité de caractères, elle doit subir une transformation avant de pouvoir être stockée. C'est pourquoi il existe différents encodages, par exemple UTF-8, qui permettent de représenter chacun des caractères.

J'ai trouvé une citation qui résume bien la différence entre la chaîne de caractères et la chaîne d'octets : « Dans un mot, la chaîne est destinée à l'affichage sur un ordinateur pour être lue sur un ordinateur et la chaîne d'octets est destinée à l'enregistrement sur disque et à la transmission de données. »1.

Modificateur de chaîne b

Pour convertir une chaîne de caractères en chaîne d'octets, il suffit d'ajouter la lettre b avant les apostrophes ou guillemets qui entourent la chaîne.

Python

chaine_octets = b"Ceci est une chaine d'octets."

Normalement, la chaîne d'octets n'est pas lisible par l'humain. Cependant, Python se charge d'effectuer un affichage symbolique pour qu'on puisse prendre connaissance de son contenu.

C'est pourquoi, si on affiche la valeur d'une chaîne d'octets, Python affichera simplement un b devant la chaîne.

Résultat à l'écran

>>> chaine_octets = b"Ceci est une chaine d'octets."
>>> print(chaine_octets)
b"Ceci est une chaine d'octets."
>>>

Avec cette technique de conversion, si on avait tenté d'utiliser un caractère accentué dans la chaîne d'octets, on aurait obtenu le message « SyntaxError: bytes can only contain ASCII literal characters. ».

Notez dans l'exemple qui suit le î dans le mot chaîne.

Résultat à l'écran

>>> chaine_octets = b"Ceci est une chaîne d'octets."
File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>>

Constructeur bytes

Une chaîne d'octets peut également être obtenue en utilisant le constructeur bytes(). Il faudra à ce moment spécifier l'encodage à utiliser.

Python

chaine_octets = bytes("Ceci est une chaine d'octets.", "utf-8")

Si on affiche cette chaîne, Python réagira comme si on avait utilisé le modificateur de chaîne b.

Python

>>> chaine_octets = bytes("Ceci est une chaine d'octets.", "utf-8")
>>> print(chaine_octets)
b"Ceci est une chaine d'octets."
>>>

L'avantage de cette technique par rapport au modificateur b, c'est qu'il est possible d'utiliser une plus grande variété de caractères puisque Python se chargera de les encoder.

Python

chaine_octets = bytes("Ceci est une chaîne d'octets.", "utf-8")

Résultat à l'écran

>>> chaine_octets = bytes("Ceci est une chaîne d'octets.", "utf-8")
>>> print(chaine_octets)
b"Ceci est une chaxc3xaene d'octets."
>>>

Méthode encode()

La méthode encode() permet elle aussi convertir une chaîne de caractères en chaîne d'octets. De plus, si l'encodage est utf-8, il n'est pas nécessaire de le spécifier.

Python

chaine_octets = "Ceci est une chaine d'octets.".encode()

Si on affiche cette chaîne, Python réagira comme si on avait utilisé le modificateur de chaîne b.

Résultat à l'écran

>>> chaine_octets = "Ceci est une chaine d'octets.".encode()
>>> print(chaine_octets)
b"Ceci est une chaine d'octets."
>>>

Ici encore, il est possible d'utiliser des caractères spéciaux.

Python

chaine_octets ="Ceci est une chaîne d'octets.".encode()

Résultat à l'écran

>>> chaine_octets = "Ceci est une chaîne d'octets.".encode()
>>> print(chaine_octets)
b"Ceci est une chaxc3xaene d'octets."
>>>

Tableau d'octets

Il ne faut pas confondre la chaîne d'octets avec le tableau d'octets (bytearray). Alors que la chaîne d'octets est immuable, le tableau d'octets peut être modifié.

Source :

1. « Quelle est la différence entre une chaîne et une chaîne d'octets? ». it-swarm-fr.com. https://www.it-swarm-fr.com/fr/python/quelle-est-la-difference-entre-une-chaine-et-une-chaine-doctets/972905528.

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre