Поведение Mutlple наследования в питоне - PullRequest
5 голосов
/ 13 февраля 2012
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 ++?

1 Ответ

8 голосов
/ 13 февраля 2012

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

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

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

* * 1010

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

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

...