关于python:super()失败,错误为:type error”当父级不从对象继承时,参数1必须是类型,而不是classobj”

super() fails with error: TypeError “argument 1 must be type, not classobj” when parent does not inherit from object

我发现了一些我无法理解的错误。有没有线索我的样本代码有什么问题?

1
2
3
4
5
6
7
8
9
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"类是

错误如下:

1
2
3
4
5
6
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

仅供参考,下面是python本身的帮助(super):

1
2
3
4
5
6
7
8
9
10
11
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)
 |


您的问题是类B没有声明为"新样式"类。像这样改变它:

1
class B(object):

它会起作用的。

super()和所有子类/超类的东西只适用于新样式的类。我建议您养成在任何类定义上输入(object)的习惯,以确保它是一个新样式的类。

旧样式类(也称为"经典"类)始终是classobj类型;新样式类是type类型。这就是您看到错误消息的原因:

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

自己试试看:

1
2
3
4
5
6
7
8
9
class OldStyle:
    pass

class NewStyle(object):
    pass

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

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

注意,在python3.x中,所有类都是新样式的。您仍然可以使用旧样式类的语法,但是您得到了一个新样式类。所以,在Python3.x中,您不会遇到这个问题。


此外,如果不能更改类B,可以使用多重继承来修复错误。

1
2
3
4
5
6
7
8
9
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)


如果python版本是3.x,就可以了。

我认为您的python版本是2.x,在添加这个代码时,super可以工作。

1
__metaclass__ = type

所以代码是

1
2
3
4
5
6
7
8
__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)

在使用python2.7时,我也遇到了发布的问题。使用python 3.4可以很好地工作

为了使它在python2.7中工作,我在程序顶部添加了__metaclass__ = type属性,它工作了。

__metaclass__:它简化了旧样式类和新样式类的转换。