En Python, lors de la définition d'une classe, vous pouvez spécifier sa classe parent. Une sous-classe hérite de toutes les propriétés et méthodes de sa classe parent et peut ajouter ses propres propriétés et méthodes uniques.
Cependant, si une classe a plusieurs classes parentes directes, il peut y avoir des propriétés et des méthodes portant le même nom entre ces classes parentes. Afin d'appeler correctement ces propriétés et méthodes, Python utilise un algorithme appelé « Method Resolution Order » (Method Resolution Order, MRO) pour déterminer l'ordre de recherche des propriétés et des méthodes.
Dans Python 2.x, MRO est implémenté à l'aide de l'algorithme de recherche en profondeur (DFS). Cet algorithme présente certains problèmes qui font que la séquence d'appels de méthode n'est pas correctement analysée dans certains cas. Par exemple :
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass d = D() d.foo() # 输出"A.foo",而不是"C.foo"
Dans le code ci-dessus, la classe D hérite de la classe B et de la classe C, et la classe C remplace la méthode foo() de la classe A. Par conséquent, lors de l’appel de la méthode foo() de l’objet d, théoriquement, la méthode foo() de la classe C devrait être appelée en premier. Cependant, puisque Python 2.x utilise l'algorithme DFS, il traversera d'abord la classe B, puis la classe C et enfin la classe A. Par conséquent, la méthode foo() de la classe A est finalement appelée, et non la méthode foo() de la classe C.
Pour résoudre ce problème, Python 2.3 a introduit l'algorithme C3, qui utilise l'algorithme de tri topologique pour calculer la liste MRO afin de garantir l'exactitude lors de l'appel des méthodes. Le principe de base de l'algorithme C3 est le suivant :
La liste MRO d'une nouvelle classe (c'est-à-dire une classe qui hérite explicitement d'un objet ou hérite implicitement d'un objet) est calculée selon l'algorithme de recherche en largeur (BFS).
Pour chaque classe, sa liste MRO doit répondre aux trois conditions suivantes :
La liste MRO de la sous-classe doit être classée devant la liste MRO de la classe parent.
Si deux classes parent apparaissent dans la liste MRO d'une classe enfant, leur ordre relatif dans la liste doit être le même que leur ordre relatif dans la classe parent directe de la classe enfant.
Une classe ne peut pas apparaître plus de deux fois dans sa liste MRO.
Cet algorithme peut gérer correctement la situation dans l'exemple de code ci-dessus, garantissant ainsi l'exactitude lors de l'appel de la méthode.
Dans Python 3, vous pouvez afficher la liste MRO d'une classe via l'attribut __mro__
. Par exemple : __mro__
属性来查看类的MRO列表。例如:
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass print(D.__mro__)
输出结果为:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
其中,<class '__main__.D'>
表示类D本身,<class '__main__.B'>
和<class '__main__.C'>
分别表示类D的父类B和C,<class '__main__.A'>
表示类B和C的共同父类A,<class 'object'>
rrreee
🎜(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)🎜Parmi eux,
🎜
<class '__main__.D'>
représente la classe D elle-même, <class '__main__.B'>
et <class '__main__.C'>
représentent respectivement les classes parent B et C de la classe D, <class '__main__.A'>
représente la classe parent commune A des classes B et C, et <class 'object'>
représente la base classe de toutes les classes de nouveau style. L'ordre de cette liste est l'ordre dans lequel les propriétés et les méthodes sont recherchées lorsque Python est en cours d'exécution. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!