Python >> Tutoriel Python >  >> Python

Sérialisation d'objets en Python

La sérialisation est une technique utile pour enregistrer des objets complexes.

Dans cet article, nous vous donnons une introduction à la sérialisation d'objets en Python et expliquons pourquoi c'est important. La sérialisation est essentiellement un moyen de stocker des données ou des objets et est une technique utile pour enregistrer des objets complexes. C'est le processus de conversion d'un objet en un flux d'octets qui peut être stocké, par exemple en mémoire ou dans un fichier. Ce fichier peut ensuite être reconstruit ou désérialisé pour récupérer l'objet d'origine, puis être réutilisé dans différents programmes voire différents environnements.

Ci-dessous, nous vous montrons quelques exemples d'utilisation de certains des outils les plus populaires pour la sérialisation en Python. Si vous débutez avec Python et que vous souhaitez développer vos compétences dans le traitement des données, consultez cette piste. Il vous apprend tout ce que vous devez savoir sur le traitement de divers formats de fichiers avec Python.

Une classe de base

Rappelez-vous que Python est un langage orienté objet; presque tout est considéré comme un objet. Cela signifie que vous pouvez sérialiser les données stockées dans une liste, un dictionnaire ou même des instances de classes.

Allons-y et créons une classe pour conduire une voiture. Cet article ne se concentre pas sur les classes, donc si vous voulez plus de détails sur le fonctionnement des classes, jetez un œil à cet article. Nous avons également du matériel qui s'appuie sur cela et vous montre comment écrire un module personnalisé en Python.

Un objet en Python a des attributs (comme ses propriétés) et des méthodes (ce qu'il peut faire). Les attributs importants pour notre catégorie de voitures sont le niveau de carburant actuel et l'efficacité (la quantité de carburant qu'elle consomme par kilomètre). Ceux-ci sont définis dans __init__() . Les voitures peuvent également être associées à plusieurs actions, telles que parcourir une certaine distance. Ce sont les méthodes de classe, qui sont écrites sous forme de fonctions au sein de la classe.

La classe suivante vous permet de conduire une voiture sur une certaine distance compte tenu de son niveau de carburant et de son efficacité :

class Car:
    def __init__(self, efficiency, fuel_level):
        self.efficiency = efficiency
        self.fuel_level = fuel_level
    
    def drive(self, distance):
        max_distance = self.fuel_level * self.efficiency
        
        if distance > max_distance:
            print('Traveled %s km, out of fuel'%(max_distance))
            self.fuel_level = 0
        else:
            self.fuel_level -= distance / self.efficiency
            print('Arrived safely!')

Nous pouvons créer un objet voiture avec une efficacité de 5 km/L et un niveau de carburant de 12 L comme suit :

fast_car1 = Car(5, 12)

Prenons-le pour un trajet de 8 km, puis vérifions le niveau de carburant :

>>> fast_car1.drive(8)
>>> fast_car1.fuel_level
10.4

Jusqu'ici tout va bien. Maintenant, nous aimerions sérialiser le fast_car1 objet afin que nous puissions revenir et l'utiliser plus tard sans avoir à l'instancier à nouveau. Entrez pickle .

cornichon

Le Python pickle module est un module facile à utiliser pour la sérialisation (pickling) et la désérialisation (unpickling) des objets en Python. Un grand nombre d'objets peuvent être décapés, y compris les booléens, les entiers, les flottants et les chaînes, ainsi que les structures de données telles que les listes, les dictionnaires, les ensembles, etc. Les fonctions et les classes peuvent être sérialisées, et comme nous le verrons ci-dessous, il en va de même instances de classes.

Le Python pickle module stocke les données sous forme binaire, elles ne sont donc pas lisibles par l'homme. Il est livré avec quatre méthodes. Les deux que nous utiliserons pour notre cas sont dump() et load() , qui enregistre et charge respectivement les fichiers pickle. Les deux autres méthodes sont dumps() et loads() , qui sérialisent les objets sans les enregistrer dans un fichier.

Nous allons examiner de plus près les deux premiers ci-dessous. Mais avant de le faire, un mot d'avertissement :comme indiqué dans la documentation officielle, le Python pickle le module n'est pas sécurisé contre les données construites de manière malveillante qui peuvent exécuter du code étranger . Par conséquent, ne décryptez jamais les données reçues d'une source non fiable .

Le briefing de sécurité terminé, continuons avec un exemple de décapage et de décapage en Python :

with open('fast_car_object.pkl', 'wb') as out_file:
    pickle.dump(fast_car1, out_file)

L'exécution de ce code produit le fichier fast_car_object.pkl dans votre répertoire de travail actuel. Pour désinstaller ce fichier, procédez simplement comme suit :

with open('fast_car_object.pkl', 'rb') as in_file:
    fast_car2 = pickle.load(in_file)

Notez les différents modes que nous utilisons pour la sérialisation ('wb ') et désérialisation ('rb '). Les deux objets fast_car1 et fast_car2 sont deux objets distincts avec des emplacements différents dans la mémoire ; cependant, ils ont les mêmes attributs et méthodes. Au fait, si vous n'êtes pas familier avec l'utilisation du with pour enregistrer un fichier, voici quelques informations sur l'écriture dans un fichier en Python.

Nous avons mentionné que presque tout en Python est un objet. Une liste est un objet, qui a des attributs et des méthodes. Par exemple, list.append() est un moyen facile d'ajouter des données arbitraires à une liste, et list.reverse() renverse les éléments. Il y en a beaucoup d'autres que vous devriez connaître. Maintenant, essayez de sérialiser une liste avec pickle comme nous l'avons fait plus haut. Ou mieux encore, essayez-le avec un dictionnaire. La structure de données imbriquée serait un peu lourde à enregistrer dans un fichier CSV ou texte, mais c'est une ligne à deux avec le pickle module.

Sérialisation JSON en Python

JSON signifie JavaScript Object Notation et est un format léger pour stocker des données. Les données stockées dans ce format ont une structure similaire à un dictionnaire Python, elles ne doivent donc pas sembler trop étrangères. Si vous n'êtes pas familiarisé avec l'utilisation de fichiers JSON, consultez ce cours. Il contient des exercices interactifs et vous apprend tout ce que vous devez savoir.

Python a un module, json , ce qui est utile si vous souhaitez encoder ou décoder des données dans ce format. Raisons de choisir cette méthode plutôt que les pickle module incluent qu'il est standardisé et indépendant de la langue . Il est également beaucoup plus sécurisé et lisible par l'homme.

Le json module peut être utilisé pour sérialiser des objets en Python. Il implémente les quatre mêmes méthodes de base que nous avons vues ci-dessus. Consultez la documentation pour plus d'informations et de nombreux autres exemples.

Commençons par un exemple simple de sérialisation d'une liste avec le json module. Ici, nous utilisons le dumps() méthode, qui n'enregistre pas les données dans un fichier mais les sérialise plutôt dans une chaîne :

	>>> import json
	>>> lst = [1, 2, 3, 'a', 'b', 'c']
	>>> lst_dump = json.dumps(lst)
	>>> lst_dump
	'[1, 2, 3, "a", "b", "c"]'

Maintenant, si nous essayons la même chose pour sérialiser notre fast_car1 objet que nous avons instancié ci-dessus, nous rencontrons un problème :

>>> car_dump = json.dumps(fast_car1)
TypeError: Object of type Car is not JSON serializable

L'encodeur JSON implémenté dans le dump() et dumps() les méthodes ne peuvent sérialiser que quelques types d'objets de base . Ce sont des dictionnaires, des listes, des chaînes, des entiers, des flottants, des booléens et aucun. Objets complexes comme fast_car1 doivent être personnalisés au format JSON en créant un encodeur personnalisé en Python.

Écrire un encodeur personnalisé

La voie à suivre se résume essentiellement à représenter les données dans un dictionnaire json peut sérialiser. Vous créez une classe d'encodeur personnalisée qui étend le JSONEncoder classe dans le json module, puis utilisez le dump() normal ou dumps() méthodes.

Examinons de plus près un exemple. Ici, la classe Car est la même que ci-dessus, et il y a maintenant une nouvelle classe, CarJSONEncoder :

from json import JSONEncoder

class Car:
    def __init__(self, efficiency, fuel_level):
        self.efficiency = efficiency
        self.fuel_level = fuel_level

    def drive(self, distance):
        max_distance = self.fuel_level * self.efficiency
        
        if distance > max_distance:
            print('Traveled %s km, out of fuel'%(max_distance))
            self.fuel_level = 0
        else:
            self.fuel_level -= distance / self.efficiency
            print('Arrived safely!')

class CarJSONEncoder(JSONEncoder):
    def default(self, obj):
        return obj.__dict__
Then to JSON serialize our object, we do the following:
>>> fast_car1_json = json.dumps(fast_car1, cls=CarJSONEncoder)
>>> fast_car1_json
'{"efficiency": 5, "fuel_level": 10.4}'

Notre classe personnalisée utilise __dict__ , qui est un attribut intégré qui stocke les attributs d'un objet sous la forme d'une paire clé/valeur. Ensuite, nous spécifions notre classe personnalisée avec le cls argument de mot-clé dans le dumps() méthode. La sortie montre notre fast_car1 objet a bien été sérialisé en JSON.

Le meilleur des deux mondes

Jusqu'à présent, nous avons exploré deux méthodes pour sérialiser des objets en Python :d'abord avec le pickle module, et deuxièmement en sérialisant en JSON avec le json module et une classe d'encodeur personnalisée. pickle est très convivial mais non lisible par l'homme et non sécurisé. json est le contraire.

Le travail acharné de combiner le meilleur de ces deux méthodes a déjà été fait pour nous, et est disponible dans le savamment nommé jsonpickle module. Ce module fournit un ensemble d'outils pour sérialiser des objets Python complexes en JSON et gère également la désérialisation. jsonpickle s'appuie sur les types d'objets de base qui sont sérialisables JSON et permet de sérialiser des objets plus complexes.

Le moyen le plus simple de mettre la main sur ce module est d'effectuer un rapide pip install commande. Ce module est livré avec la même étiquette d'avertissement qui vient avec pickle . Ne l'utilisez pas pour désérialiser des données provenant d'une source non fiable .

Sa fonctionnalité est similaire à ce que nous avons déjà vu dans cet article, nous n'entrerons donc pas trop dans les détails ici. Inutile de dire qu'il est livré avec le encode() méthode pour sérialiser et decode() pour désérialiser. Il est également hautement personnalisable. Consultez la documentation si vous voulez plus de détails et quelques exemples rapides.

Maîtriser la sérialisation d'objets en Python

Nous espérons avoir démystifié ce qu'est la sérialisation d'objets en Python. Nous vous avons montré quelques outils utiles pour vous aider à mieux gérer vos programmes et vos données. Assurez-vous de vous salir les mains et jouez avec les exemples présentés ici. Ensuite, vous aurez maîtrisé un autre aspect de Python en un rien de temps !