Super() с ошибкой: TypeError "аргумент 1 должен быть типом, а не classobj"

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

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

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

print C().meth(1)

Я получил образец тестового кода с помощью встроенного метода "супер". Класс "C" - это

Вот ошибка:

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

FYI, вот помощь (супер) из самого python:

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)
 |

Ответы

Ответ 1

Ваша проблема в том, что класс 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 у вас не будет этой проблемы.

Ответ 2

Кроме того, если вы не можете изменить класс 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)

Ответ 3

Если версия 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)

Ответ 4

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

Чтобы он работал в python 2.7, я добавил атрибут __metaclass__ = type в верхней части моей программы, и он сработал.

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