Tutoriel Python & Pickle : manipuler les fichiers binaires
Table des matières
1.1. Modes d'ouverture d’u fichier binaire
1.2. Les formats de protocole du module pickle Python
1.4. Cas d'utilisation de Pickle
- Ecrire sur un fichier binaire: Pickling (sérialiser)
- Lecture d'un fichier binaire via python: Unpickling (dé-sérialiser)
- Utilisation du module Pickle avec Pandas
- Les dangers d’utilsation de Pickle
- Exercices
Introduction
Si vous êtes un développeur Python débutant, intermédiaire ou senior, vous serez toujours amenés à gérer des fichiers en local. La gestion des fichiers n'est rien d'autre qu'une combinaison de diverses opérations effectuées sur les fichiers telles que l'ouverture du fichier, la lecture du fichier, l'écriture du fichier, etc.
Il existe généralement deux types de fichiers: les fichiers texte et les fichiers binaires. Un fichier texte stocke les informations textuelles, par exemple, tout message disant "Hello World" et enregistré sous l'extension .txt, tandis que les images sont stockées sous la forme de nombres binaires tels que 0 ou 1 et enregistrées sous l'extension .bin.
Lorsque l'analyse des données implique de grandes quantités de données, il est préférable de les utiliser au format binaire. Il existe ainsi plusieurs outils en Python pour gérer les données binaires, à savoir : Pickle.
Ainsi, à la fin de ce tutoriel, vous découvrirez et maitriserez les opérations sur les fichiers les plus fréquemment utilisés à l’aide de Pickle, notamment:
- Ouverture et lecture d'un fichier binaire.
- Création et écriture un nouveau fichier binaire.
1. Qu'est-ce qu'un fichier binaire ?
Un fichier binaire est un fichier dont le contenu doit être interprété par un programme ou un processeur matériel qui comprend à l'avance exactement comment il est formaté. Un programme doit savoir comment les données à l'intérieur du fichier sont disposées pour utiliser le fichier en question. En informatique, chaque fichier n'est qu'une pile de 1 et de 0. Lors de l'ouverture d'un fichier binaire dans un éditeur de texte, ce dernier ressemble à ceci :
Un fichier binaire n'est rien de plus qu'un système numérique. Il est généralement constitué d’une séquence d'octets, ce qui signifie que les chiffres binaires (bits) sont regroupés en huit.
2. Le module Pickle
Pickle est utilisé pour sérialiser et désérialiser des structures d'objets Python, également appelées marshalling ou aplatissement. La sérialisation fait référence au processus de conversion d'un objet en mémoire à un flux d'octets qui peut être stocké sur un disque ou envoyé sur un réseau. Plus tard, ce flux de caractères peut être récupéré et désérialisé en un objet Python. Le dé-sérialisation ne doit pas être confondu avec la compression! Le premier est la conversion d'un objet d'une représentation (données dans la mémoire vive (RAM)) à une autre (texte sur disque), tandis que le second est le processus d'encodage de données avec moins de bits, afin d'économiser de l'espace disque.
Le module pickle implémente un algorithme puissant pour la sérialisation et le dé-sérialisation d'une structure de données implémentée en Python. Le décapage est le processus par lequel la hiérarchie d'un objet est convertie en un flux d'octets.
Cela permet à un objet d'être transmis et stocké, puis d'être reconstruit par le récepteur lui-même en conservant toutes les caractéristiques d'origine. En Python, l'opération de picking est réalisée par le module Pickle
1.1. Modes d'ouverture d’u fichier binaire
Il existe plusieurs modes d’ouverture d’un fichier binaire, à savoir :
- wb: écriture uniquement. Remplace le fichier binaire s'il existe. Sinon, crée un nouveau fichier binaire pour l'écriture.
- wb +: écriture et lecture. Remplace le fichier binaire s'il est fermé. Sinon, crée un nouveau fichier binaire pour l'écriture.
- rb: lecture seule. Définit le pointeur de fichier au début du fichier binaire.
- rb +: lecture et écriture. Définit le pointeur de fichier au début du fichier binaire
1.2. Les formats de protocole du module pickle Python
Comme mentionné ci-dessus, le module pickle est spécifique à Python et le résultat d'un processus de sérialisation ne peut être lu que par un autre programme Python. Même si vous travaillez avec Python, il est important de savoir que le module pickle a évolué au fil du temps.
Cela signifie que si vous avez sélectionné un objet avec une version spécifique de Python, vous ne pourrez peut-être pas le décoller avec une version plus ancienne. La compatibilité dépend de la version du protocole que vous avez utilisée pour le processus d’ Unpickling.
Il existe actuellement six protocoles différents que le module pickle Python peut utiliser. Plus la version du protocole est élevée, plus l'interpréteur Python doit être récent pour le décoller. Nous mentionnons les différentes versions existantes du protocole du module Pickle :
- La version 0 du protocole était la première version. Contrairement aux protocoles ultérieurs, elle est lisible par l'homme.
- La version 1 du protocole était le premier format binaire.
- La version 2 du protocole a été introduite dans la version Python 2.3.
- La version 3 du protocole a été ajoutée dans la version Python 3.0. Elle ne peut pas être annulé par Python 2.x.
- La version 4 du protocole a été ajoutée à Python 3.4. Elle prend en charge une gamme plus large de tailles et de types d'objets et c’est également la version par défaut à partir de Python 3.8.
- La version 5 du protocole a été ajoutée dans Python 3.8. Elle prend en charge les données hors bande et des vitesses améliorées pour les données en bande.
Les versions les plus récentes du protocole offrent plus de fonctionnalités et d'améliorations, mais elles sont limitées par rapport aux versions supérieures de l'interpréteur. Veillez à prendre ceci en considération lors du choix du protocole à utiliser.
Pour identifier le protocole le plus élevé pris en charge par votre interpréteur, vous pouvez vérifier la valeur de l'attribut pickle.HIGHEST_PROTOCOL.
Pour choisir un protocole spécifique, vous devez spécifier la version du protocole lorsque vous appelez load (), charges (), dump () ou dumps (). Si vous ne spécifiez pas de protocole, votre interpréteur utilisera la version par défaut spécifiée dans l’attribut pickle.DEFAULT_PROTOCOL.
1.3. Que peut-on pickler?
Afin de stocker des données avec Pickle, vous devez savoir ce qui peut être sérialisé directement ainsi que les diverses solutions de contournement pour les types de données dits Unpicklable. Les éléments suivants peuvent être picklés:
- Booléens
- Entiers
- Flotteurs
- Nombres complexes,
- (normales et Unicode) chaînes,
- Tuples,
- Listes,
- Dictionnaires contenant des objets picklables.
Vous pouvez également sélectionner des classes et des fonctions, si elles sont définies au niveau supérieur d'un module.
1.4. Cas d'utilisation de Pickle
Le Pickling est utile pour les applications où vous avez besoin d'un certain degré de persistance de vos données. Les données d'état de votre programme peuvent être enregistrées sur le disque, vous pouvez donc continuer à travailler dessus plus tard. Il peut également être utilisé pour envoyer des données via une connexion TCP (Transmission Control Protocol) ou socket, ou pour stocker des objets Python dans une base de données. Pickle est très utile lorsque vous travaillez avec des algorithmes d'apprentissage automatique, où vous souhaitez les enregistrer pour pouvoir faire de nouvelles prédictions plus tard, sans avoir à tout réécrire ou à ré entraîner le modèle.
2. Ecrire sur un fichier binaire: Pickling (sérialiser)
La sérialisation (également appelée Pickling) est un processus de conversion de la hiérarchie d'objets Python en flux d'octets afin qu'elle puisse être écrite dans un fichier.
Exemple :
Pour cet exemple, nous enregistrerons des chaînes, des entiers et des booléens dans un fichier binaire :
Syntaxe :
import pickle
données = {
'a': [1, 4, 3, 6],
'b': ("Bienvenue à cours-gratuit.com"),
'c': {True, False}
}
with open('données.bin', 'wb') as fichier:
pickle.dump(data, fichier, pickle.HIGHEST_PROTOCOL)
La fonction dump permet d’écrire la représentation dé-sérialisée de l'objet dans l'objet fichier. Au fil du temps, plusieurs protocoles ont été développés. La version du protocole détermine les capacités du processus de sérialisation. Dans notre code, nous choisissons la version de protocole la plus élevée.
Résultat de l’exécution :
Dans votre répertoire, vous trouverez qu'il existe un fichier binaire créé appelé données.bin :
Si vous avez essayé de l'ouvrir avec un éditeur de texte, le résultat ressemblerait à ceci :
Les fichiers binaires ne peuvent pas être lus avec de simples éditeurs de texte; nous avons besoin d'outils capables de manipuler des données hexadécimales.
3. Lecture d'un fichier binaire via python: Unpickling (dé-sérialiser)
Le dé-sérialisation ou Unpickling est l'inverse du processus de Pickling où un flux d'octets est converti en une hiérarchie d'objets. Alors que le processus de récupération des objets Python originaux à partir de la représentation sous forme de chaîne stockée est appelé unpickling, nous utilisons la fonction Load pour ce faire. Dans l'exemple suivant, nous allons utiliser des données à partir d'un fichier binaire que nous avons créé dans l'exemple précédent :
Syntaxe :
import pickle
with open('données.bin', 'rb') as fichier:
données = pickle.load(fichier)
print(données)
Résultat d’exécution :
La fonction load permet de lire la représentation binaire d'un objet à partir de l'objet fichier et de renvoyer l'objet reconstitué.
4. Utilisation du module Pickle avec Pandas
Parfois, un DataFrame peut contenir des données qui ne seront pas bien enregistrées au format texte (ex: csv). Par exemple, un DataFrame peut contenir des listes, et celles-ci seront enregistrées sous forme de chaînes de texte au format texte.
Python a une bibliothèque (pickle) pour sauvegarder les objets Python intacts afin qu'ils puissent être sauvegardés et chargés sans avoir à les générer à nouveau.
Pandas a intégré la capacité de «pckling» qui facilite la sauvegarde et le chargement des données intactes.
Commençons par générer un dataframe contenant des listes :
Syntaxe :
my_df = pd.DataFrame()
noms = ['John', Alex, Joe, 'Billy']
sports_favoris= [['Tennis', Basket],
['Football', 'Handball', 'Hockey'],
['Table tennis', 'crossfit', 'Athletics'],
[nattation]]
my_df[noms] = noms
my_df['sports_favoris'] = sports
with open(données-pandas, 'wb') as fichier:
pickle.dump(my_df, fichier)
Résultat d’exécution:
Pour lire le fichier que vous avez enregistré avec Pandas et Pickle, utilisez cette syntaxe :
Syntaxe :
import pickle
with open('données-pandas.bin', 'rb') as fichier:
données = pickle.load(fichier)
print(données)
Résultat d’exécution :
Cette méthode peut également être utilisée avec d'autres types d'objets Python complexes (tels que des modèles d'apprentissage automatique entraînés).
5. Les dangers d’utilsation de Pickle
Il est important de mentionner les inconvénients ou les dangers dus à l’utilisation du module Pickle. Il faut savoir que dans ce contexte, il n’existe pas un traitement une interprétation de l'objet Python, car il est Unpicklé ou décoché. C'est un processus extrêmement simple et efficace, et c'est là que réside son seul risque. Il est possible de subir des conséquences involontaires sur votre ordinateur ou d'être victime d'un code malveillant si vous dé-sérialisez un fichier d'origine inconnue ou non fiable. Donc, bien que ce soit un bon conseil générique, je vous conseille vivement une pratique simple en ce qui concerne les fichiers pickle ... NE L'UTILISEZ PAS SAUF POUR VOTRE PROPRE CODE! Cette règle simple devrait vous éviter les ennuis.
6. Exercices
6.1. Exercice 1
Considérez la liste de couleurs suivante :
couleurs = jaune, rouge, bleu, vert, blanc, noir
- Essayez de convertir la liste en fichier binaire en utilisant la méthode dump avec le protocole le plus élevé.
- Chargez le même fichier en utilisant la méthode load.
7. Solution des exercices
7.1. Exercice 1
- Tout d'abord, nous devons importer le module pickle, comme mentionné dans la ligne 1 du code. Puis, nous définissons une simple liste de couleurs qui seront dé-sérialisés. Nous déclarons également le nom de notre fichier pickle de sortie : liste_couleurs. Ensuite, en utilisant l'option wb, nous indiquons au programme que nous voulons écrire (w) des données binaires (b) à l'intérieur (car nous voulons créer un flux d'octets). Dans la dernière ligne, nous utiliserons la méthode pickle.dump () pour sélectionner notre liste de couleurs et la stocker dans le fichier couleurs.bin.
Syntaxe :
import pickle
liste_couleurs = ['jaune', 'rouge', 'bleu','vert','blanc','noir']
with open('couleurs.bin', 'wb') as fichier:
pickle.dump(liste_couleurs, fichier ,pickle.HIGHEST_PROTOCOL)
Résultat d’exécution :
- Maintenant, dé-sérialisons le contenu du fichier de pickle et ramenons notre objet à sa forme d'origine.
Syntaxe
import pickle
with open('couleurs.bin', 'rb') as fichier:
unpickled_liste = pickle.load(fichier)
print(unpickled_liste)
Résultat d’exécution :
Conclusion
Comme vous pouvez l’identifier, grâce au module Pickle, la sérialisation des objets Python est assez simple. Dans nos exemples, nous avons sélectionné une simple liste Python - mais vous pouvez utiliser exactement la même méthode pour enregistrer un large éventail de types de données Python, à condition de vous assurer que vos objets ne contiennent que d'autres objets picklables.
Le dé-sérialisation présente certains inconvénients, dont le plus important pourrait être le fait que vous ne pouvez lire vos données qu'en utilisant Python - si vous avez besoin d'une solution multilingue, JSON est certainement une meilleure option. Et enfin, rappelez-vous que les pickles peuvent être utilisés pour transporter le code que vous ne voulez pas nécessairement exécuter. Comme pour les aliments marinés, tant que vous obtenez vos cornichons de sources fiables, tout devrait bien se passer.
Article publié le 26 Novembre 2020 par Mouhtat Bilal