Python super () вызывает TypeError - PullRequest
       49

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

105 голосов
/ 28 января 2009

В 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 ]

128 голосов
/ 28 января 2009

Причина в том, что 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
14 голосов
/ 01 февраля 2009

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

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

 X.a(self)
3 голосов
/ 15 марта 2017

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

# 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
1 голос
/ 02 апреля 2012

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

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

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

X().a(self)
...