super () завершается с ошибкой: TypeError «аргумент 1 должен быть типом, а не classobj», если родительский объект не наследуется от объекта - PullRequest
176 голосов
/ 11 ноября 2009

Я получаю ошибку, которую не могу понять. Любая подсказка, что не так с моим примером кода?

class B:
    def meth(self, arg):
        print arg

class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

Я получил тестовый код с помощью встроенного метода 'super'. Класс "С" является

Вот ошибка:

Traceback (most recent call last):
  File "./test.py", line 10, in ?
    print C().meth(1)
  File "./test.py", line 8, in meth
    super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj

К вашему сведению, вот помощь (супер) от самого питона:

Help on class super in module __builtin__:

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super(C, self).meth(arg)
 |

Ответы [ 4 ]

292 голосов
/ 11 ноября 2009

Ваша проблема в том, что класс B не объявлен как класс "нового стиля". Измените это так:

class B(object):

и будет работать.

super() и все подклассы / суперклассы работают только с классами нового стиля. Я рекомендую вам всегда набирать (object) в любом определении класса, чтобы убедиться, что это новый класс.

Классы старого стиля (также известные как "классические" классы) всегда имеют тип classobj; классы нового стиля имеют тип type. Вот почему вы получили сообщение об ошибке:

TypeError: super() argument 1 must be type, not classobj

Попробуйте, чтобы убедиться в этом:

class OldStyle:
    pass

class NewStyle(object):
    pass

print type(OldStyle)  # prints: <type 'classobj'>

print type(NewStyle) # prints <type 'type'>

Обратите внимание, что в Python 3.x все классы выполнены в новом стиле. Вы все еще можете использовать синтаксис из классов старого стиля, но вы получите класс нового стиля. Таким образом, в Python 3.x у вас не будет этой проблемы.

129 голосов
/ 23 августа 2013

Кроме того, если вы не можете изменить класс B, вы можете исправить ошибку, используя множественное наследование.

class B:
    def meth(self, arg):
        print arg

class C(B, object):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)
15 голосов
/ 05 августа 2015

Если версия Python 3.X, все в порядке.

Я думаю, что ваша версия Python 2.X, супер будет работать при добавлении этого кода

__metaclass__ = type

так что код

__metaclass__ = type
class B:
    def meth(self, arg):
        print arg
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)
print C().meth(1)
3 голосов
/ 28 февраля 2017

Я также столкнулся с опубликованной проблемой, когда использовал Python 2.7. Очень хорошо работает с питоном 3.4

Чтобы это работало в Python 2.7 Я добавил атрибут __metaclass__ = type вверху моей программы, и он работал.

__metaclass__: облегчает переход от классов старого стиля и классов нового стиля.

...