Поведение наследования Mutlple в python

In [5]: class a(object):
   ...:     def __init__(self):
   ...:         print "In class a"
   ...:         self.a = 1
   ...:         
In [6]: class b(object):
   ...:     def __init__(self):
   ...:         print "In class b"
   ...:         self.b = 2
   ...:         
   ...:         

In [7]: class c(b, a):
   ...:     pass
   ...: 
In [8]: c.mro()
Out[8]: 
[<class '__main__.c'>,
 <class '__main__.b'>,
 <class '__main__.a'>,
 <type 'object'>]

In [9]: obj = c()
In class b

In [10]: obj.__dict__
Out[10]: {'b': 2}

Метод по умолчанию __init__ класса c вызывается при создании obj, который внутренне вызывает __init__ только класса b.

Насколько я понимаю, если я наследую от класса 2, мой объект производного класса должен иметь переменные из обоих классов (если только они не являются частными для этих классов).

Мой вопрос: я ошибаюсь, ожидая, что мой производный объект будет содержать переменные из обоих классов? Если да, то почему? Не следует ли также вызывать __init__ класса a? Что произошло бы на таком языке, как C++?


person avasal    schedule 13.02.2012    source источник
comment
jcollado ответ правильный. Подробнее о том, как работает super, см. этот ответ.   -  person perelman    schedule 13.02.2012


Ответы (1)


В python методы инициализации из высших классов по умолчанию не вызываются. Для этого вы должны явно вызывать их с помощью super следующим образом:

class a(object):
    def __init__(self):
        super(a, self).__init__()
        print "In class a"
        self.a = 1

class b(object):
    def __init__(self):
        super(b, self).__init__()
        print "In class b"
        self.b = 2

class c(b, a):
    pass

obj = c()

Пример вывода.

В классе а
В классе б

Изменить: Что касается того, почему это работает таким образом, я бы сказал, что это проектное решение, основанное на Дзен Python:

Явное лучше неявного.

person jcollado    schedule 13.02.2012
comment
почему super(b, self).__init__() вызывает __init__ метод a, a не является суперклассом b, означает ли это, что синтаксис вызывает следующий объект в последовательности mro? - person avasal; 13.02.2012
comment
@avasal, да, вызов super найдет следующий доступный метод в последовательности mro. Обратите внимание, что приведенный код работает только потому, что object.__init__ существует и вызывается без аргументов: если __init__ в классах принимает аргумент или вы хотите распространить другой метод, вам может понадобиться промежуточный класс-заглушка, чтобы завершить цепочку вызовов super. См. также rhettinger.wordpress.com/2011/05/26/super -считается-супер - person Duncan; 13.02.2012