2010-03-28 2 views
4

Я нахожу этот синтаксис поразительно раздражающим. Каждый раз, когда я переименовываю свой класс, я должен изменить этот вызов без видимых причин. Разве нет какой-то __class__ волшебной переменной или что-то, что я могу использовать хотя бы? Заинтересованы в ответах на Python 2.5, но не мешает узнать, исправили ли в дальнейшем версии.Способ вызова super (MyClass, self) .__ init __() без MyClass?

+0

Вы не одиноки: http://www.python.org/dev/peps/pep-3135/ –

ответ

3

Если ваш класс только наследует от один класса это безопасно делать только это:

class B(A): 
    def __init__(self): 
     A.__init__(self) 

Но я мог бы ошибаться.

+0

Нет ошибки - так оно и работает. –

+0

Ох .. хорошо, это не так уж плохо! Почему бы это не работать, если он наследуется от более чем одного класса? Вы явно говорите, какой из них вы хотите использовать ... – mpen

+0

@Mark: Да, конечно, вы можете явно перечислить каждый класс, на который наследуется ваш класс. Но я не знаю, как 'super()' работает внутри, поэтому, возможно, он делает некоторые сложные вещи для инициализации всего в правильном порядке. Я больше думал о том, что вы должны использовать метод 'super()' для вызова любого родителя, поскольку он гарантирует, что вызывается правильный метод, если класс наследуется от более чем одного класса. Вот почему я написал * safe *, поскольку я определенно уверен в этом с одним классом, но не с тем, как он ведет себя с большим количеством классов. –

4

Насколько я знаю, это невозможно в 2.5. Однако в версии 3.0 это было изменено, так что вы можете просто позвонить super().__init__().

2

В Python 3.0 super() можно вызвать без аргументов, чтобы сделать то же самое.

-1

EDIT: Как указано Алексом, это приводит к бесконечной рекурсии, когда существует более чем один уровень наследования. Не используйте этот подход.

Да, «новые» классы стиля имеют атрибут __class__, который может быть использован, например.

class B(object): 
    def __init__(self): 
     print "B.__init__():" 

class D(B): 
    def __init__(self): 
     print "D.__init__():" 
     super(self.__class__, self).__init__() 

>>> d = D() 
D.__init__(): 
B.__init__(): 

>>> dir(d) 
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__'] 
>>> d.__class__ 
<class '__main__.D'> 

Однако это не удается, если класс был наследовать от D:

>>> class E(D): 
...  pass 
... 
>>> E() 
D.__init__(): 
D.__init__(): 
[...] 
D.__init__(): 
D.__init__(): 
Traceback (most recent call last): 
    File "<stdin>", line 4, in __init__ 
    File "<stdin>", line 4, in __init__ 
    [...] 
    File "<stdin>", line 4, in __init__ 
    File "<stdin>", line 4, in __init__ 
RuntimeError: maximum recursion depth exceeded while calling a Python object 
+7

** неправильный **! Добавьте 'class E (D): pass' и попробуйте выполнить' e = E() ': вы получаете исключение с максимальной глубиной перегрева, потому что' D .__ init__' вызывает себя ('self .__ class__' is' E 'поэтому его' супер' '' 'D * -> бесконечная рекурсия). –

+0

@Alex Martelli: Звучит разумно. –

+0

Да, спасибо за это. Я тоже это заметил. – mhawke

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