【问题标题】:Python super() raises TypeErrorPython super() 引发 TypeError
【发布时间】:2010-10-04 02:34:40
【问题描述】:

在 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),它将起作用。对此有何解释?

【问题讨论】:

标签: python inheritance python-2.x super


【解决方案1】:

原因是super()只对new-style classes起作用,在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

【讨论】:

  • 从哪个 python 版本成为默认行为?
  • 2.2 是引入新样式类的时候,3.0 是它们成为默认类的地方。
  • @tsunami 如果你想进入超类,请执行“X.a(self)”
  • 我想你误会了。三联画。我记得我使用的是低于 3.0 的 python 版本,并且我没有特别说我的类继承自 Object ,并且对 super 的调用有效。也许这是 2.6 的默认行为?只是说:)
  • 雪花石膏,真的没必要。新式班有很多好处,不仅仅是超级。不应推广旧式方式。
【解决方案2】:

此外,除非必须,否则不要使用 super()。对于您可能怀疑的新型类,这不是通用的“正确做法”。

有时您期望多重继承并且您可能想要它,但在您了解 MRO 的繁琐细节之前,最好不要管它并坚持:

 X.a(self)

【讨论】:

  • 这是正确的,因为在我使用 Python/Django 的 6 个月中,我一直在使用 super 作为“一般正确的做法”?
  • 好吧,单继承本身并没有伤害你(除了它有点慢),但它本身也没有给你任何东西。您必须设计任何需要乘法继承的方法(最值得注意的是__init__)以干净且合理的方式传递参数,否则当有人尝试使用您的类进行乘法继承时,您会遇到 TypeError 或更严重的调试问题.除非您真的设计为以这种方式支持 MI(这很棘手),否则最好避免暗示 super 认为该方法是 MI 安全的。
  • 这似乎是个坏建议。
【解决方案3】:

我尝试了各种 X.a() 方法;但是,它们似乎需要一个 X 的实例才能执行 a(),所以我做了 X().a(self),这似乎比以前的答案更完整,至少对于我遇到的应用程序而言。由于存在不必要的构造和破坏,这似乎不是处理问题的好方法,但它工作正常。

我的具体应用是 Python 的 cmd.Cmd 模块,由于某种原因,它显然不是 NewStyle 对象。

最终结果:

X().a(self)

【讨论】:

    【解决方案4】:

    如果以上答案都没有明确提及。您的父类需要从“对象”继承,这实际上会将其变成一个新的样式类。

    # 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
    

    【讨论】:

    • 抱歉,但在 Python 3.x 中,您的第二个示例(隐式继承)在提到的问题的上下文中并不真正起作用。
    猜你喜欢
    • 2016-06-20
    • 2012-03-30
    • 2018-03-12
    • 2019-01-23
    • 1970-01-01
    • 2013-09-26
    • 2017-08-14
    • 1970-01-01
    • 2020-01-27
    相关资源
    最近更新 更多