Python Language Héritage multiple


Exemple

Python utilise l'algorithme de linéarisation C3 pour déterminer l'ordre de résolution des attributs de classe, y compris les méthodes. Ceci est connu comme l'Ordre de Résolution de Méthode (MRO).

Voici un exemple simple:

class Foo(object):
    foo = 'attr foo of Foo'
    

class Bar(object):
    foo = 'attr foo of Bar' # we won't see this.
    bar = 'attr bar of Bar'

class FooBar(Foo, Bar):
    foobar = 'attr foobar of FooBar'

Maintenant, si nous instancions FooBar, si nous recherchons l'attribut foo, nous voyons que l'attribut de Foo est trouvé en premier

fb = FooBar()

et

>>> fb.foo
'attr foo of Foo'

Voici le MRO de FooBar:

>>> FooBar.mro()
[<class '__main__.FooBar'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <type 'object'>]

On peut simplement dire que l’algorithme MRO de Python est

  1. Profondeur d'abord (par exemple FooBar puis Foo ) à moins que
  2. un parent partagé ( object ) est bloqué par un enfant ( Bar ) et
  3. aucune relation circulaire autorisée.

C'est-à-dire que, par exemple, Bar ne peut pas hériter de FooBar alors que FooBar hérite de Bar.

Pour un exemple complet en Python, voir l' entrée Wikipedia .

Une autre fonctionnalité puissante dans l'héritage est super . super peut récupérer les fonctionnalités des classes parentes.

class Foo(object):
    def foo_method(self):
        print "foo Method"

class Bar(object):
    def bar_method(self):
        print "bar Method"

class FooBar(Foo, Bar):
    def foo_method(self):
        super(FooBar, self).foo_method()

Héritage multiple avec la méthode init de la classe, lorsque chaque classe a sa propre méthode d'initialisation, alors nous essayons d'inférencer plusieurs fois, alors seule la méthode init est appelée de classe qui est héritée en premier.

pour exemple ci - dessous seule méthode init Foo classe se classe appelé Bar INIT pas appelé

    class Foo(object):
        def __init__(self):
            print "foo init"

    class Bar(object):
        def __init__(self):
            print "bar init"

    class FooBar(Foo, Bar):
        def __init__(self):
            print "foobar init"
            super(FooBar, self).__init__()

    a = FooBar()

Sortie:

    foobar init
    foo init

Mais cela ne signifie pas que la classe Bar n'est pas héritée. L'instance de la classe FooBar finale est également une instance de la classe Bar et de la classe Foo .

print isinstance(a,FooBar)
print isinstance(a,Foo)
print isinstance(a,Bar) 

Sortie:

True
True
True