Serpy est un package Python qui permet sérialiser en json n'importe quel objet.
Serpy permet d'implémenter facilement et rapidement les méthodes __str__ et __repr__ d'une classe.
Il permet également d'implémenter une méthode dumps.
Exemple avec la classe suivante:
import serpy
import json
from decimal import Decimal
class Personne(object):
def __init__(self, firstname: str, lastname: str, sexe: str, age: int, salaire: float, position: dict):
self.firstname = firstname
self.lastname = lastname
self.sexe = sexe
self.age = age
self.salaire = salaire
self.position = position
Cette classe permet de créer un objet Personne.
L'argument position est un dictionnaire dans lequel on renseigne une latitude et une longitude. Il devra contenir les 2 clés 'latitude' et 'longitude'.
Je vais maintenant créer deux nouvelles classes, qui vont permettre de sérialiser mon objet Personne et mon sous-objet Position.
class PositionSerializer(serpy.DictSerializer):
latitude = serpy.FloatField()
longitude = serpy.FloatField()
class PersonneSerializer(serpy.Serializer):
firstname = serpy.StrField()
lastname = serpy.StrField()
sexe = serpy.MethodField()
age = serpy.IntField()
salaire = serpy.FloatField()
position = PositionSerializer()
def get_sexe(self, obj):
if obj.sexe == 'M':
return 'Homme'
elif obj.sexe == 'F':
return 'Femme'
else:
return 'N/A'
La classe PersonneSerializer étend la classe serpy.Serializer.
Elle reprend les différents arguments de la classe Personne en indiquant pour chaque argument son type Serpy (StrField, IntField, FloatField).
Le type particulier MethodField permet d'associer une méthode à l'argument afin d'effectuer des calculs spécifiques. La méthode doit être nommée comme le nom de l'argument précédé du terme 'get_'
Il est également possible d'associer à l'argument une classe qui permet de sérialiser le contenu de l'objet. Dans mon exemple, l'argument position est une dictionnaire qui contient 2 données décimales. La classe PositionSerializer étend la classe serpy.DictSerializer et reprend les 2 clés de mon objet dict position.
Je vais maintenant modifier ma classe Personne afin d'y ajouter les 3 méthodes __str__, __repr__ et dumps.
class Personne(object):
def __init__(self, firstname: str, lastname: str, sexe: str, age: int, salaire: float, position: dict):
self.firstname = firstname
self.lastname = lastname
self.sexe = sexe
self.age = age
self.salaire = salaire
self.position = position
def __str__(self):
return json.dumps(PersonneSerializer(self).data, indent=4)
def __repr__(self):
return json.dumps(PersonneSerializer(self).data)
def dumps(self):
return PersonneSerializer(self).data
La méthode __str__ retourne mon objet sérialisé au format json via la classe PersonneSerializer.
La méthode __repr__ retourne également mon objet sérialisé au format json via la classe PersonneSerializer mais sans mise en forme.
La méthode dumps retourne mon objet sérialisé via la classe PersonneSerializer.
Et voici le résultat:
personne1 = Personne(firstname='Matthieu', lastname='Lopes', sexe='M', age=43, salaire=1509.56,
position={'latitude': Decimal('-55.5232795'), 'longitude': Decimal('157.460948')})
print(f'{" Personne 1 ":-^30}')
print(repr(personne1))
print(personne1)
dumps = personne1.dumps()
print(type(dumps))
print(dumps)
personne2 = Personne(firstname='Constance', lastname='Lopez', sexe='F', age=87, salaire=2056.35,
position={'latitude': Decimal('-56.710608'), 'longitude': Decimal('-154.540259')})
print('')
print(f'{" Personne 2 ":-^30}')
print(repr(personne2))
print(personne2)
dumps = personne2.dumps()
print(type(dumps))
print(dumps)
--------- Personne 1 ---------
{"firstname": "Matthieu", "lastname": "Lopes", "sexe": "Homme", "age": 43, "salaire": 1509.56, "position": {"latitude": -55.5232795, "longitude": 157.460948}}
{
"firstname": "Matthieu",
"lastname": "Lopes",
"sexe": "Homme",
"age": 43,
"salaire": 1509.56,
"position": {
"latitude": -55.5232795,
"longitude": 157.460948
}
}
<class 'dict'>
{'firstname': 'Matthieu', 'lastname': 'Lopes', 'sexe': 'Homme', 'age': 43, 'salaire': 1509.56, 'position': {'latitude': -55.5232795, 'longitude': 157.460948}}
--------- Personne 2 ---------
{"firstname": "Constance", "lastname": "Lopez", "sexe": "Femme", "age": 87, "salaire": 2056.35, "position": {"latitude": -56.710608, "longitude": -154.540259}}
{
"firstname": "Constance",
"lastname": "Lopez",
"sexe": "Femme",
"age": 87,
"salaire": 2056.35,
"position": {
"latitude": -56.710608,
"longitude": -154.540259
}
}
<class 'dict'>
{'firstname': 'Constance', 'lastname': 'Lopez', 'sexe': 'Femme', 'age': 87, 'salaire': 2056.35, 'position': {'latitude': -56.710608, 'longitude': -154.540259}}
Le résultat est parfait.