2012-02-13 6 views
5
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.Поведение наследования Mutlple в питона

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

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

+0

Ответ jcollado правильный. См. [Этот ответ] (http://stackoverflow.com/q/607186) для более подробной информации о том, как работает 'super'. – perelman

ответ

8

В 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() 

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

в классе А
В классе б

Edit: Относительно того, почему это работает таким образом, я бы сказал, что это проектное решение на основе The Zen of of Python:

Явная является лучше, чем неявное.

+0

Почему 'super (b, self) .__ init __()' call '__init__' метод a, a не является суперклассом b, означает ли это, что синтаксис вызывает следующий объект в последовательности mro? – avasal

+0

@avasal, да, вызов 'super' найдет следующий доступный метод в последовательности mro. Обратите внимание, что приведенный код работает только потому, что 'object .__ init__' существует и вызывается без аргументов: если' __init__' в классах принял аргумент или вы хотите использовать другой метод, вам может понадобиться промежуточный класс-заглушка для завершения цепочка 'супер' вызывает. См. Также http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ – Duncan

Смежные вопросы