Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > Множественное наследование


Автор: Artemios 20.10.2006, 16:56
Код

>>> class A:
...         def __init__(self):
...             self.a = 1
...
>>> class B:
...         def __init__(self):
...             self.b = 5
...
>>> class C(A,B):
...         pass
...
>>> c = C()
>>> c.__dict__
{'a': 1}

>>> class D(A,B):
...         def __init__(self):
...             pass
...
>>> d = D()
>>> d.__dict__
{}

>>> class E(A,B):
...     def __init__(self):
...         A.__init__(self)
...         B.__init__(self)
...
>>> e = E()
>>> e.__dict__
{'a': 1, 'b': 5}
>>>


Непонятна ситуация с классом C.

Автор: slivlen 20.10.2006, 18:47
Код

>>> class C(A,B):
...         def __init__(self):
...             pass
...
>>> c = C()
>>> c.__dict__
{}

А так все нормально smile

Автор: cherep 20.10.2006, 18:48
А что конкретно не ясно-то? Вроде все логично.. Если ты не переопределил конструктор (как в классе C), то при создании экземпляра этого класса будет вызван конструктор первого суперкласса, т.е. A. На то оно и наследование...

Автор: slivlen 20.10.2006, 18:54
Цитата(cherep @  20.10.2006,  18:48 Найти цитируемый пост)
А что конкретно не ясно-то? Вроде все логично.. Если ты не переопределил конструктор (как в классе C), то при создании экземпляра этого класса будет вызван конструктор первого суперкласса, т.е. A. На то оно и наследование... 

Точняк smile

Автор: Daevaorn 20.10.2006, 20:23
Цитата(cherep @  20.10.2006,  19:48 Найти цитируемый пост)
Вроде все логично

Логично вызвать конструкторы всех подобъектов, а не только первого, разве нет? А то получается: мама родилась, а папа нет.

Автор: J2A 21.10.2006, 09:40
Daevaorn, считаешь что так более правильно - убеди товарищей из python-dev. Только предварительно не забудь написать патч, который меняет поведение Python на нужное тебе.

Автор: setq 21.10.2006, 12:14
cherep, не то чтобы очень логично. С точки зрения того, что у класса может быть только один метод __init__ и поэтому по правилам поиска выбирается __init__ первого базового класса -- да. С точки зрения того "как должно быть правильно" -- наверно всё-таки нет.

Автор: Artemios 21.10.2006, 12:33
Цитата(setq @  21.10.2006,  12:14 Найти цитируемый пост)
у класса может быть только один метод __init__ и поэтому по правилам поиска выбирается __init__ первого базового класса

Понятно, спасибо.

Цитата(setq @  21.10.2006,  12:14 Найти цитируемый пост)
С точки зрения того "как должно быть правильно" -- наверно всё-таки нет. 

на этом меня и "глюкнуло" smile

Автор: cherep 21.10.2006, 13:57
Цитата

Логично вызвать конструкторы всех подобъектов, а не только первого, разве нет? А то получается: мама родилась, а папа нет. 


Как раз это менее логично, хотябы по тому, что explicit is better than implicit. Порядок перечисления суперклассов при определении нового класса , ну то есть 
Код

class A(B, C, D, E):
    pass


определяет прежде всего порядок перекрытия одноименных методов и полей в т.ч. и конструктора.

Или Вы считаете что вызов A().meth(arg) должен приводить к B.meth(self, arg), C.meth(self, arg) и т.д. - это глупо, т.к. такое поведение редко надо, а если надо, то достигается явным (explicit) определением:
Код

class A(B, C, D, E):
    def meth(self, arg):
        B.meth(self, arg)
        C.meth(self, arg)


Ровно таким же образом можно задать и вызов всех конструкторов, если нужно.

Автор: Daevaorn 21.10.2006, 14:02
Цитата(cherep @  21.10.2006,  14:57 Найти цитируемый пост)
Как раз это менее логично, хотябы по тому, 

Ну я, по крайней мере, знаю один язык программирования с множественным наслодованием, где именно такое поведениеsmile

У каждого языка свои особенности. Поэтому запомним, что python ведет себя так, а не иначе.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)