Python: La class avec Serpy

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.

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.