Python super() вызывает TypeError

В Python 2.5.2 следующий код вызывает TypeError:

>>> class X:
...   def a(self):
...     print "a"
...
>>> class Y(X):
...   def a(self):
...     super(Y,self).a()
...     print "b"
...
>>> c = Y()
>>> c.a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj

Если я заменил class X на class X(object), он будет работать. Какое объяснение этому?

Ответ 1

Причина в том, что super() работает только с классами нового стиля, что в серии 2.x означает расширение от объекта.

Ответ 2

Кроме того, не используйте super(), если вам не нужно. Это не универсальная "правильная вещь" делать с классами нового стиля, которые вы можете заподозрить.

Бывают случаи, когда вы ожидаете множественного наследования, и вы, возможно, захотите этого, но пока вы не узнаете волосатые детали MRO, лучше оставить его в покое и придерживаться:

 X.a(self)

Ответ 3

В случае, если ни один из вышеперечисленных ответов не сказал это четко. Ваш родительский класс должен наследовать от "объекта", который по существу превратит его в новый класс стиля.

# python 3.x:
class ClassName(object): # This is a new style class
    pass

class ClassName: # This is also a new style class ( implicit inheritance from object )
    pass

# Python 2.x:
class ClassName(object): # This is a new style class
    pass

class ClassName:         # This is a old style class
    pass

Ответ 4

Я попробовал различные методы X.a(); однако они, похоже, требуют экземпляра X для выполнения a(), поэтому я сделал X(). a (self), который кажется более полным, чем предыдущие ответы, по крайней мере для приложений, с которыми я столкнулся. Это не похоже на хороший способ справиться с этой проблемой, поскольку есть ненужная конструкция и разрушение, но она отлично работает.

Моим конкретным приложением был модуль Python cmd.Cmd, который по какой-то причине, по-видимому, не является объектом NewStyle.

Итоговый результат:

X().a(self)