Cours
L'une des séquences intégrées les moins connues de Python est bytes, qui est une séquence immuable d'entiers. Chaque nombre entier représente un octet de données. Les données sont souvent transmises par les réseaux et les programmes sous forme d'octets. Les octets ne sont pas lisibles par l'homme et nous devons souvent les convertir en chaînes de caractères dans nos programmes Python.
Ce tutoriel explore les techniques de conversion d'octets en chaînes de caractères en Python. Si l'opération inverse vous intéresse, consultez mon tutoriel sur la conversion de chaînes de caractères en octets en Python.
Commençons par une réponse courte pour ceux d'entre vous qui sont pressés.
Réponse courte : Comment convertir des octets en chaînes de caractères en Python
Le principal outil pour convertir des octets en chaînes de caractères en Python est la méthode .decode()
:
data = b"\xc3\xa9clair"
text = data.decode(encoding="utf-8")
print(text)
éclair
La méthode .decode()
renvoie une chaîne de caractères représentant l'objet bytes
. Dans cet exemple, le décodage UTF-8 est utilisé. UTF-8 est l'encodage par défaut, il n'est donc pas nécessaire dans l'exemple ci-dessus, mais nous pouvons également utiliser d'autres encodages.
Comprendre les octets et les chaînes de caractères en Python
Python dispose d'une structure de données intégrée bytes
, qui est une séquence immuable d'entiers compris entre 0 et 255. Un nombre entier compris dans cette plage de 256 nombres peut être représenté en utilisant huit bits de données, ce qui équivaut à un octet. Par conséquent, chaque élément d'un objet bytes
est un nombre entier représentant un octet.
Utilisons le constructeur bytes()
pour créer un objet bytes
à partir d'une liste :
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(type(data))
<class 'bytes'>
Cette séquence d'entiers est immuable :
data[0] = 100
Traceback (most recent call last):
...
data[0] = 100
~~~~^^^
TypeError: 'bytes' object does not support item assignment
Python soulève un TypeError
lorsque nous essayons de modifier une valeur au sein de cette séquence. Confirmons qu'un objet bytes
ne peut contenir que des nombres entiers compris entre 0 et 255 :
data = bytes([254, 255, 256])
Traceback (most recent call last):
...
data = bytes([254, 255, 256])
^^^^^^^^^^^^^^^^^^^^^^
ValueError: bytes must be in range(0, 256)
Le site ValueError
indique qu'un nombre entier représentant un octet doit être membre de range(0, 256)
. La fin de la plage est exclue, comme c'est la convention avec une plage de nombres en Python.
Nous pouvons afficher l'objet bytes à l'aide de print()
:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(data)
b'DataCamp'
La représentation montre l'objet bytes
représenté par des caractères. Python affiche les entiers en utilisant les caractères ASCII correspondant à ces valeurs. Le préfixe b précédant les caractères entre guillemets indique qu'il s'agit d'un objet bytes
.
Nous pouvons également créer un objet bytes
en utilisant directement le littéral bytes :
data = b"DataCamp"
print(data)
print(data[0])
b'DataCamp'
68
L'objet est affiché en utilisant des caractères, mais ses éléments sont des nombres entiers.
Toutefois, les objets bytes
ne sont lisibles par l'homme que si l'on utilise des nombres entiers correspondant à des caractères ASCII imprimables. L'ASCII étant un codage sur 7 bits, il contient 128 codes, mais seuls 95 de ces caractères ASCII sont imprimables.
Les nombres entiers compris entre 0 et 127 qui n'ont pas de caractère ASCII imprimable et les nombres entiers compris entre 128 et 255 sont affichés sous forme de nombres hexadécimaux :
data = bytes([0, 68, 97, 116, 97, 67, 97, 109, 112, 200])
print(data)
b'\x00DataCamp\xc8'
Le premier entier de la liste est maintenant 0, qui n'est pas un caractère imprimable en ASCII. L'objet bytes
affiche cet entier sous la forme \x00
, la représentation hexadécimale de 0. L'entier final est 200, ce qui est en dehors de la plage ASCII mais dans la plage des entiers qui peuvent être utilisés en octets. Python affiche cet entier sous la forme \xc8
, soit 200 en hexadécimal.
Les structures de données bytes
et strings présentent des caractéristiques communes. Il s'agit de deux séquences immuables, mais bytes
contient des nombres entiers, tandis que les chaînes contiennent des caractères :
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
print(data[0])
text = "DataCamp"
print(text[0])
68
D
Les octets sont utilisés pour transférer des données sur les réseaux et entre différentes interfaces. La section suivante de cet article explique comment convertir des octets en chaînes de caractères.
Conversion d'octets en chaînes de caractères : Le .decode()
Méthode
En Python, un objet bytes
n'est lisible par l'homme que s'il contient des caractères ASCII lisibles. Dans la plupart des applications, ces caractères ne sont pas suffisants. Nous pouvons convertir un objet bytes
en une chaîne de caractères à l'aide de la méthode .decode()
:
data = bytes([68, 97, 116, 97, 67, 97, 109, 112])
text = data.decode()
print(text)
print(type(text))
DataCamp
<class 'str'>
Cependant, il existe différents encodages pour convertir les octets en chaînes de caractères. Les nombres entiers dans l'exemple ci-dessus représentent des caractères ASCII imprimables. Cependant, le codage par défaut utilisé lorsqu'aucun argument n'est transmis à .decode()
est UTF-8 et non ASCII. UTF-8 est le codage le plus répandu pour les caractères Unicode.
Les 128 premiers codes UTF-8 correspondent aux codes ASCII, ce qui explique pourquoi les données de l'objet bytes sont décodées sous la forme de la chaîne "DataCamp"
dans l'exemple ci-dessus.
Cependant, Unicode contient près de 150 000 caractères. UTF-8 code tous les caractères non ASCII en Unicode en utilisant deux octets ou plus.
Créons un nouvel objet bytes
et décodons-le :
data = bytes([195, 169])
print(data)
text = data.decode()
print(text)
b'\xc3\xa9'
é
L'objet bytes
contient deux octets : les entiers 195 et 169. Python affiche la représentation hexadécimale de ces octets. Cependant, .decode()
renvoie une chaîne de caractères en décodant l'objet bytes
à l'aide de l'encodage UTF-8. La paire d'octets b'\xc3\xa9'
représente la lettre e avec un accent aigu, é.
La méthode .decode()
prend un argument facultatif pour spécifier l'encodage :
text = data.decode("utf-8")
print(text)
é
UTF-8 est le codage par défaut, mais d'autres codages peuvent être utilisés. Nous pouvons également convertir une chaîne de caractères en un objet bytes
à l'aide de la méthode string .encode()
avec différents encodages :
text = "éclair"
data = text.encode("utf-8")
print(data)
data = text.encode("utf-16")
print(data)
b'\xc3\xa9clair'
b'\xff\xfe\xe9\x00c\x00l\x00a\x00i\x00r\x00'
La même chaîne de caractères est convertie en différents objets bytes
en fonction de l'encodage de caractères utilisé.
Erreurs d'encodage
Le choix des encodages de caractères peut entraîner des erreurs si un encodage différent est utilisé lors de la conversion entre les octets et les chaînes de caractères. Prenons l'exemple de la chaîne "éclair"
encodée en octets à l'aide de l'encodage UTF-8 :
text = "éclair"
data = text.encode("utf-8")
print(data)
b'\xc3\xa9clair'
Cette séquence d'octets représente des caractères utilisant le codage UTF-8. La méthode .decode()
soulève une erreur si nous utilisons le mauvais encodage :
text = data.decode("ascii")
print(text)
Traceback (most recent call last):
...
text = data.decode("ascii")
^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Cependant, nous pouvons inclure l'argument optionnel errors
pour gérer les éventuelles erreurs. La valeur par défaut du paramètre errors
est "strict"
, ce qui entraîne une erreur en cas de caractères non valides.
La méthode .decode()
peut être appelée avec errors="ignore"
pour ignorer tous les caractères non valides :
text = data.decode("ascii", errors="ignore")
print(text)
clair
Le premier caractère de la chaîne originale est é, qui n'est pas un caractère ASCII. Par conséquent, .decode()
renvoie une chaîne sans le premier caractère.
Une autre option consiste à appeler .decode()
avec errors="replace"
, qui remplace les octets non valides par des � :
text = data.decode("ascii", errors="replace")
print(text)
��clair
Cette sortie montre qu'il manque des caractères dans la chaîne. Le choix du traitement des erreurs dépend de l'application.
Conversion d'octets en chaînes de caractères avec str()
La méthode .decode()
est le principal moyen de convertir des octets en chaînes de caractères. Cependant, il est également possible d'utiliser directement le constructeur str()
. L'utilisation du constructeur str()
sur un objet bytes
créera une représentation sous forme de chaîne de caractères des octets bruts :
data = b'\xc3\xa9clair'
text = str(data)
print(text)
print(type(text))
b'\xc3\xa9clair'
<class 'str'>
Cependant, le constructeur str()
accepte également un argument encoding
, que nous pouvons utiliser pour créer une chaîne de caractères basée sur un encodage spécifique :
text = str(data, encoding='utf-8')
print(text)
éclair
Convertir des octets en chaînes de caractères avec codecs.decode()
Le module codecs
de la bibliothèque standard de Python fournit l'interface pour le codage et le décodage des données. Ce module fournit également une fonction .decode()
qui peut être utilisée pour convertir des octets Python en chaînes de caractères :
import codecs
data = b'\xc3\xa9clair'
text = codecs.decode(data, encoding='utf-8')
print(text)
éclair
Ces techniques de conversion alternatives ne sont pas des méthodes du type bytes
mais des fonctions qui nécessitent la transmission de l'objet bytes
en tant qu'argument.
Conclusion
Les données sont souvent transférées sous forme d'octets, et de nombreuses applications Python doivent faire la conversion entre les octets et les chaînes de caractères. Un objet bytes
est une séquence immuable d'octets qui peut être convertie en string
à l'aide d'un des nombreux codages de caractères.
La principale méthode de conversion des octets de Python en chaîne de caractères est la méthode .decode()
, qui permet aux utilisateurs de choisir un encodage et une stratégie de traitement des erreurs.
Vous pouvez poursuivre votre apprentissage de Python avec les tutoriels et cours suivants :
J'ai étudié la physique et les mathématiques au niveau UG à l'université de Malte. J'ai ensuite déménagé à Londres et obtenu un doctorat en physique à l'Imperial College. J'ai travaillé sur de nouvelles techniques optiques pour obtenir des images de la rétine humaine. Aujourd'hui, je me concentre sur l'écriture, la communication et l'enseignement de Python.