Accéder au contenu principal

Découvrir les méthodes magiques de Python

Découvrez ce que sont les méthodes magiques tout en distinguant méthodes et fonctions.
Actualisé 19 sept. 2026  · 11 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

L’une des raisons qui font de Python un langage si puissant est l’existence des méthodes magiques. Dans certains cercles de Pythonistas, vous les entendrez aussi appeler « dunder methods », en référence aux doubles underscores qui les encadrent. 

Leur rôle en Python est de réaliser ce qu’on appelle la « surcharge d’opérateurs » : un opérateur prédéfini se voit attribuer un sens étendu. Autrement dit, la surcharge permet d’ajouter des comportements personnalisés à nos classes pour les rendre compatibles avec les opérateurs de Python et ses fonctionnalités natives.  

Dans cet article, nous allons approfondir les méthodes magiques de Python en : 

  • Faisant la distinction entre méthodes et fonctions 
  • Expliquant ce que sont les méthodes magiques
  • Fournissant des exemples Python concrets. 

Consultez ce cahier DataLab pour suivre le code utilisé dans ce tutoriel. 

Méthodes Python vs fonctions

Avant d’expliquer ce que sont les méthodes magiques, il faut comprendre la différence entre une méthode et une fonction en Python. 

Python utilise les méthodes pour représenter le comportement d’un objet. Elles sont donc liées à un objet et effectuent des opérations sur les données qu’il contient. Un autre élément distinctif est le paramètre self, qui doit toujours être le premier paramètre passé à la méthode. 

Remarque : ce n’est pas obligatoirement le mot self qui doit être utilisé comme premier paramètre, mais la communauté Python s’accorder à dire que c’est une bonne pratique. 

# Example of a method
class Human:
    # This is a method
    def walk(self):
        print("I am walking") 

Les méthodes dépendent de la classe à laquelle elles sont associées. Ainsi, pour appeler une méthode, il faut d’abord créer une instance de la classe, puis y accéder via l’opérateur point. 

# This will work
joe = Human()
joe.walk()

"""
I am walking
"""




# This will throw a NameError
walk()

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/tmp/ipykernel_153/2327344440.py in <module>
      4
      5 # This will throw a NameError
----> 6 walk()

NameError: name 'walk' is not defined

Une fonction, en revanche, est différente : nul besoin de créer une instance de classe. 

Les fonctions Python sont des étapes exécutées en bloc uniquement lorsqu’elles sont appelées. Elles sont définies indépendamment de toute classe, ce qui signifie qu’on peut les appeler directement par leur nom. Comme elles ne sont pas liées à une classe, il n’est pas nécessaire de passer self en paramètre – les paramètres sont optionnels. 

En substance, une fonction est un ensemble d’instructions définies que l’interpréteur utilise pour accomplir une tâche. 

# Example of a function
def run():
  print("I am running.")
​
run()

"""
I am running.
"""

Comme nous l’indiquons dans notre article Comment écrire et appeler des fonctions, les fonctions existent sous deux formes : natives et définies par l’utilisateur. 

  • Fonctions natives : des fonctions incluses dans la bibliothèque standard de Python. 
  • Fonctions définies par l’utilisateur : Python permet à l’utilisateur de définir ses propres fonctions et de les utiliser dans un programme Python.  

Sur bien des points, méthodes et fonctions se ressemblent : elles sont par exemple toutes deux définies avec def. La différence fondamentale est que les méthodes sont liées à un objet et opèrent sur les données d’une classe, tandis que les fonctions sont définies indépendamment et peuvent être appelées par leur nom n’importe où dans un programme. 

Que sont les méthodes magiques de Python ?

Au début du tutoriel, nous avons mentionné que les méthodes magiques sont également appelées dunder methods à cause de leur double underscore. Concrètement, toutes les méthodes magiques commencent et se terminent par deux underscores. 

La méthode magique la plus connue est __init__, qui permet d’initialiser une classe avec des attributs spécifiques. 

class Employee:
    def __init__(self, name, age, role):
        self.name = name
        self.age = age
        self.role = role

Pour instancier cette classe, il faut préciser les attributs name, age et role de l’instance. Par exemple :

user_1 = Employee(name="John", age=24, role="Data Scientist")

Sinon, Python lèvera une TypeError

La méthode __init__ appartient à la catégorie des méthodes d’initialisation et de construction, mais ce n’est que l’une d’entre elles. Le tableau ci-dessous présente d’autres méthodes de cette catégorie. 

__new__(cls, other)

Utilisée pour créer une nouvelle instance d’une classe

__init__(self, other)

Appelée après la création d’une nouvelle instance ; tous les attributs passés au constructeur de la classe sont utilisés comme attributs. 

__del__(self)

Aussi appelée destructeur ; appelée lorsque l’instance doit être détruite. 

La façon la plus simple d’imaginer les méthodes magiques est d’y voir un contrat entre votre implémentation et l’interpréteur Python. Une des clauses prévoit que Python exécute certaines actions en coulisses dans des circonstances données, par exemple l’initialisation d’une instance avec des attributs spécifiques. 

Autrement dit, vous n’avez pas à appeler directement une méthode magique : Python s’en charge pour vous, en arrière-plan. 

Méthodes de représentation textuelle

Python est un langage orienté objet (POO) : tout est objet. Lorsqu’on crée un nouvel objet, on crée implicitement un objet lié, car toutes les classes héritent d’object.  

Remarque : vous pouvez aussi rendre cet héritage explicite en passant la classe object à votre classe. 

# This works
class Car:
  pass
​
# This also works
class Vehicle(object):
  pass
​
car = Car()
vehicle = Vehicle()
​
print(car, vehicle, sep="\n")

"""
<__main__.Car object at 0x7f80449dc0a0>
<__main__.Vehicle object at 0x7f80449dc1f0>
"""

Dans le code ci-dessus, nous avons créé deux classes vides, mais l’interpréteur savait tout de même quoi afficher avec print. C’est possible parce que toutes les classes héritent de la classe object (la mère de toutes les classes en Python), qui possède une méthode magique __repr__ que print appelle pour renvoyer une valeur au programme principal.  

Si vous connaissez l’héritage, vous savez qu’une classe fille peut surcharger une méthode de sa classe parente en définissant une méthode du même nom. 

# Overriding the object __repr__
class Vehicle:
  def __repr__(self):
      return f"{self.__class__.__qualname__}"
​
vehicle = Vehicle()
print(vehicle)

"""
Vehicle
"""

Vous pouvez aussi utiliser la méthode magique __str__ pour produire une représentation textuelle appelée par print. 

En réalité, __repr__ sert de solution de repli à __str__. Ainsi, lorsqu’on appelle print, Python cherche d’abord une méthode __str__ définie dans votre classe, puis se rabat sur __repr__ si besoin. 

# Using __str__ for string representation
class Vehicle:
  def __str__(self):
      return f"{self.__class__.__qualname__}"
     
vehicle = Vehicle()
print(vehicle)

"""
Vehicle
"""

Le tableau ci-dessous récapitule d’autres méthodes magiques liées à la représentation textuelle. 

__str__(self)

Appelée par la fonction native str() de Python et par print pour afficher la représentation informelle d’un objet. Elle n’a pas besoin d’être une expression Python valide. 

__repr__(self)

Appelée par la fonction native repr() et lors des conversions de chaînes pour afficher la représentation officielle d’un objet. Idéalement, cela doit ressembler à une expression Python valide, mais une chaîne descriptive utile est préférable si ce n’est pas possible. 

__unicode__(self)

Appelée pour implémenter la fonction native unicode() et retourner un objet Unicode. 

__hash__(self)

Appelée par la fonction native hash() et lors des opérations sur les membres des collections hachées. La méthode doit retourner un entier. 

__nonzero__(self)

Appelée par l’opération bool() pour les tests de vérité. La méthode doit retourner True ou False (ou leur équivalent entier 1 ou 0). 

Méthodes « magiques » d’encapsulation 

L’encapsulation est l’un des principes fondamentaux de la POO. Elle consiste à regrouper les données avec les méthodes qui les manipulent, ou à restreindre l’accès direct à certains composants d’un objet.

Les développeurs venant d’autres langages orientés objet critiquent souvent le manque d’encapsulation stricte des classes en Python. Ils sont habitués à des modificateurs explicites pour les méthodes ou les champs, afin de définir par exemple des attributs privés avec des getters et setters publics. En Python, une grande partie de l’encapsulation passe par les méthodes magiques. 

Par exemple, __setattr__ est une solution d’encapsulation qui permet de définir un comportement lors de l’affectation à un attribut, qu’il existe déjà ou non. Autrement dit, on peut poser des règles sur les modifications de valeurs des attributs. 

import string

class Alphabet():
    def __setattr__(self, name, value):
        self.__dict__[name] = value.upper()

a = Alphabet()

# Assinging an attribute that does not exist
# The setattr should convert it to caps despite being set as lowercase
a.alphabet = string.ascii_lowercase
print(a.alphabet)

Dans le code ci-dessus, nous avons créé une classe Alphabet sans attributs, mais nous avons indiqué à Python de mettre en majuscules tout attribut affecté à l’instance.

Nous savons que la POO peut sembler ardue pour certains lecteurs. Pour vous mettre à niveau en Python orienté objet, découvrez le parcours Python Programmer de DataCamp.   

Méthodes magiques pour les opérations mathématiques

Une autre catégorie de méthodes magiques concerne les opérateurs arithmétiques. Les expressions utilisent des symboles spéciaux appelés « opérateurs » en Python. Utiliser ces opérateurs dans des expressions suppose que les objets implémentent les méthodes magiques adéquates. À défaut, une TypeError sera levée. 

class Numbers:
  def __init__(self, a, b):
      self.a = a
      self.b = b
   
set_a = Numbers(2, 4)
set_b = Numbers(3, 5)
​
print(set_a + set_b)
"""
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_152/3639634723.py in <module>
      7 set_b = Numbers(3, 5)
      8
----> 9 print(set_a + set_b)

TypeError: unsupported operand type(s) for +: 'Numbers' and 'Numbers'
"""

Ici, nous avons tenté d’additionner deux instances de la classe Numbers, ce qui déclenche logiquement une erreur. Une première solution serait d’écrire une méthode pour additionner les nombres, mais cela nous empêcherait d’utiliser des expressions. 

Une meilleure approche consiste à implémenter la méthode magique __add__ comme suit :  

# Using add operator
class Numbers:
    def __init__(self, a, b):
        self.a = a
        self.b = b
   
    def __add__(self, other):
        # Only permit Numbers objects to be added
        if not isinstance(other, Numbers):
            return NotImplemented
        return Numbers(other.a + self.a, other.b + self.b)
   
    def __repr__(self):
      return f"{self.__class__.__qualname__}({self.a}, {self.b})"
   
a = Numbers(2, 4)
b = Numbers(3, 5)
print(a + b) # Should result in Numbers(5, 9)


"""
RandomNumbers(5, 9)
"""

Le code ci-dessus nous permet uniquement d’additionner deux objets Numbers. Implémentons une autre méthode magique pour autoriser la multiplication d’un objet Numbers par un entier. 

# Multiplying Numbers with an integer
class Numbers:
    def __init__(self, a, b):
        self.a = a
        self.b = b
   
    def __add__(self, other):
        # Only permit Numbers objects to be added
        if not isinstance(other, Numbers):
            return NotImplemented
        return Numbers(other.a + self.a, other.b + self.b)
   
    def __mul__(self, other):
      if not isinstance(other, int):
          return NotImplemented
         
      return Numbers(self.a * other, self.b * other)
   
    def __repr__(self):
      return f"{self.__class__.__qualname__}({self.a}, {self.b})"
   
a = Numbers(2, 4)
print(a * 5) # Should return 10, 20




"""
RandomNumbers(10, 20)
"""

Nous avons ajouté __mul__ pour permettre la multiplication des valeurs de notre classe personnalisée par un entier. 

Remarquez que l’objet Numbers se trouve à gauche de l’opérateur *. Ce n’est pas un hasard. Plaçons-le à droite et observons le résultat. 

- snip --

a = Numbers(2, 4)
print(3 * a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_152/2857655049.py in <module>
      1 a = Numbers(2, 4)
----> 2 print(3 * a)

TypeError: unsupported operand type(s) for *: 'int' and 'Numbers'

Python lève une TypeError. 

Notre __mul__ ne gère que le cas où l’objet Numbers est à gauche de l’opérateur *. Pour étendre la fonctionnalité, ajoutons la méthode magique inverse __rmul__. 

# Enabling reverse multiplication
class Numbers:
    def __init__(self, a, b):
        self.a = a
        self.b = b
   
    def __add__(self, other):
        # Only permit Numbers objects to be added
        if not isinstance(other, Numbers):
            return NotImplemented
        return Numbers(other.a + self.a, other.b + self.b)
   
    def __mul__(self, other):
      if not isinstance(other, int):
          return NotImplemented
      return Numbers(self.a * other, self.b * other)

    def __rmul__(self, other):
        return self.__mul__(other)
   
    def __repr__(self):
      return f"{self.__class__.__qualname__}({self.a}, {self.b})"
   
a = Numbers(2, 4)
print(5 * a) # Should return 10, 20

"""
Numbers(10, 20)
"""

Nous pouvons désormais écrire une expression de multiplication sans nous soucier du côté de l’opérateur où se trouve l’objet Numbers. 

Conclusion

Le principe de base pour exploiter les méthodes magiques en Python reste le même : créez une classe et redéfinissez les méthodes magiques de la classe object. Il en existe un grand nombre, et un tutoriel exhaustif serait beaucoup trop long. Nous vous recommandons vivement de consulter la documentation Python pour avoir une idée de l’étendue des méthodes magiques à votre disposition afin d’améliorer vos compétences en programmation Python.  



Sujets
Python

Cours sur Python

Cours

Python intermédiaire

4 h
1.4M
Mettez à niveau vos compétences en science des données en créant des visualisations à l'aide de Matplotlib et en manipulant des DataFrame avec pandas.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow