super()失败并出现错误:当父不从对象继承时,TypeError"参数1必须是type,而不是classobj"

Ehs*_*ghi 186 python inheritance object parent super

我得到一些我无法弄清楚的错误.任何线索我的示例代码有什么问题?

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

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

print C().meth(1)
Run Code Online (Sandbox Code Playgroud)

我从"超级"内置方法的帮助下得到了示例测试代码."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
Run Code Online (Sandbox Code Playgroud)

仅供参考,这是来自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)
 |
Run Code Online (Sandbox Code Playgroud)

ste*_*eha 311

您的问题是B类未被声明为"新式"类.像这样改变它:

class B(object):
Run Code Online (Sandbox Code Playgroud)

它会起作用.

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'>
Run Code Online (Sandbox Code Playgroud)

请注意,在Python 3.x中,所有类都是新式的.您仍然可以使用旧式类的语法,但是您将获得一个新式类.所以,在Python 3.x中你不会遇到这个问题.


frm*_*ryr 144

此外,如果您无法更改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)
Run Code Online (Sandbox Code Playgroud)

  • 我忍不住发表评论,这个应该被接受为"标准"答案. (15认同)
  • 对于未来的googlers坚持使用Python 2.6:这是你可能想要的答案!当您无法更改基类(例如,您正在为标准库类创建子类)时,对您自己的类的更改将修复super(). (9认同)
  • 'object'作为第二个父类是一个很好的技巧. (2认同)

小智 18

如果python版本是3.X,那没关系.

我认为你的python版本是2.X,超级版在添加这段代码时会起作用

__metaclass__ = type
Run Code Online (Sandbox Code Playgroud)

所以代码是

__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)
Run Code Online (Sandbox Code Playgroud)


JON*_*JON 5

当我使用 python 2.7 时,我也遇到了发布的问题。它在 python 3.4 上工作得很好

为了使其在 python 2.7 中工作,我__metaclass__ = type在程序顶部添加了该属性并且它工作正常。

__metaclass__ :它简化了旧式类和新式类的过渡。