Licence CC BY-NC-ND Thierry Parmentelat

classes : rappels (2)

les méthodes spéciales (aussi appelées dunder methods)

méthodes spéciales / dunder methods

  • sur une classe on peut définir des méthodes spéciales

  • pour bien intégrer les objets dans le langage

  • c’est-à-dire donner du sens à des constructions du langage

e.g. que peuvent vouloir dire :

  • avec les fonctions builtin, e.g. len(obj), int(obj)

  • opérateurs comme obj + x

  • itération for item in obj

  • test d’appartenance x in obj

  • indexation obj[x]

  • même appel! obj(x)

  • etc…

len(obj)

class Classe:
    
    def __init__(self, students):
        self.students = students
        
    def __len__(self):
        return len(self.students)
classe = Classe(['jean', 'laurent', 'benoit'])

len(classe)
3

de manière similaire :

  • __int__(self) pour redéfinir int(obj) et similaires

bool(obj)

class Classe:
    
    def __init__(self, students):
        self.students = students
        
    def __bool__(self):
        return self.students != []
classe1 = Classe([])
classe2 = Classe(['jean', 'laurent', 'benoit'])

if not classe1:
    print("classe1 est fausse")
if classe2:
    print("classe2 est vraie")
classe1 est fausse
classe2 est vraie

opérateurs

class Classe:
    
    def __init__(self, students):
        self.students = students
        
    def __add__(self, other):
        return Classe(self.students + other.students)
    
    def __repr__(self):
        return f"[{len(self.students)} students]"
classe1 = Classe(['marie', 'claire'])
classe2 = Classe(['jean', 'laurent'])

classe1 + classe2
[4 students]

itérations

class Classe:

    def __init__(self, students):
        self.students = students

    def __iter__(self):
        return iter(self.students)
classe = Classe(['jean', 'laurent', 'benoit'])

for s in classe:
    print(s)
jean
laurent
benoit

appartenance

class Classe:

    def __init__(self, students):
        self.students = students

    def __contains__(self, student):
        return student in self.students
classe = Classe(['jean', 'laurent', 'benoit'])

'jean' in classe
True

indexations

class Classe:

    def __init__(self, students):
        self.students = students

    def __getitem__(self, index):
        if isinstance(index, int):
            return self.students[index]
        elif isinstance(index, str):
            if index in self.students:
                return index
            else:
                return None
classe = Classe(['jean', 'laurent', 'benoit'])

classe[1]
'laurent'
classe['jean']
'jean'
classe['pierre'] is None
True

appel

on peut même donner du sens à obj(x)

class Line:
    """
    modelling the line of equation
    y = ax + b
    """
    def __init__(self, a, b):
        self.a = a
        self.b = b
        
    def __call__(self, x):
        return self.a * x + self.b
# cet objet se comporte
# comme une fonction

line = Line(2, 2)


# c'est intéressant de pouvoir l'appeler
# comme si c'était une fonction

line(1)
4

pour en savoir plus

la liste exhaustive des méthodes spéciales est donnée dans la documentation officielle ici

https://docs.python.org/3/reference/datamodel.html#special-method-names

résumé

une classe peut définir des méthodes spéciales

  • notamment le constructeur pour l’initialisation,

  • souvent un afficheur pour print()

  • optionnellement d’autres pour donner du sens à
    des constructions du langage sur ces objets

  • ces méthodes ont toutes un nom en __truc__ (dunder methods)