0

Dans mon code, j'ai la relation d'héritage B -> C -> D, et il y a une fonction particulière f d'intérêt iciEn héritage multiple python, est-il possible pour un parent d'accéder à un autre parent sans savoir ce que ce parent est?

class C(B): 
    def f(self): 
     if <some condition>: 
      B.f(self) 
     else: 
      <do other stuff> 

Et la question est qu'il existe de multiples possibilités de B en réalité, mais la logique de C est le même. Une façon simple est alors d'utiliser l'héritage linéaire à plusieurs reprises, à savoir,

B1 -> C1 -> D1 
B2 -> C2 -> D2 
B3 -> C3 -> D3 

Cependant, il est inutile. Ensuite, je pense à l'aide de l'héritage multiple

D1(C, B1) 
D2(C, B2) 
D3(C, B3) 

Ensuite, le problème est de savoir comment C.f() accès B1.f() (même pour B2, B3) car il ne connaît que l'existence de B1 via D1?

Est-ce une mauvaise idée d'utiliser l'héritage multiple dans ce cas? Ou y at-il un meilleur moyen que l'héritage linéaire simple avec plusieurs C s et l'héritage multiple (si cela fonctionne)?

Répondre

1

Il s'agit d'un problème classique sur l'héritage multiple qui a finalement conduit certaines langues à se désengager de l'héritage multiple. Cependant, Python s'en est sorti en mettant en place un algorithme de "résolution de résolution de méthode" (mro) astucieusement conçu, et plus tard, avec l'avènement de l'appel intégré super. L'algorithme et son historique sont détaillés dans https://www.python.org/download/releases/2.3/mro/

Mais, depuis longtemps, il fonctionne comme prévu "par coeur". Par exemple, en collant ce code sur l'interpréteur interactif:

class A: pass 
class B(A): 
    def f(self): raise NotImplementedError 
class C(B): 
    def f(self): 
     super().f() 
     print("C") 
class B1(B): f = lambda s: print("B1") 
class B2(B): f = lambda s: print("B2") 
class D(C, B1): pass 
class D1(C, B2): pass 

Nous obtenons ces résultats lors de bricoler le long:

In [25]: D().f() 
B1 
C 

In [26]: D1().f() 
B2 
C 

In [27]: D.__mro__ 
Out[27]: (__main__.D, __main__.C, __main__.B1, __main__.B, __main__.A, object)