ChatGPT解决这个技术问题 Extra ChatGPT

Python super() 引发 TypeError

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

您的“但是我用 X 类(对象)替换 X 类”解决了我的问题!谢谢

p
poke

原因是 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 如果您想进入超类,请执行“Xa(self)”
我想你误会了我。三联画。我记得我使用的是低于 3.0 的 python 版本,我没有特别说我的类继承自 Object ,并且对 super 的调用有效。也许这是 2.6 的默认行为?只是说:)
雪花石膏,真的没必要。新式课程有很多好处,不仅仅是超级。不应该提倡旧式的方式。
b
bobince

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

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

 X.a(self)

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

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

# 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 中,您的第二个示例(隐式继承)在提到的问题的上下文中并不能真正起作用。
Z
Zoran Pavlovic

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

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

最后结果:

X().a(self)