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

В Python 2.5 следующий код поднимает 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), это будет работать. Чем это объясняется?

4 ответа

Решение

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

>>> class X(object):
        def a(self):
            print 'a'

>>> class Y(X):
        def a(self):
            super(Y, self).a()
            print 'b'

>>> c = Y()
>>> c.a()
a
b

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

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

 X.a(self)

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

# 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

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

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

Конечный результат:

X().a(self)
Другие вопросы по тегам