在 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)
,它将起作用。对此有何解释?
原因是 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
此外,除非必须,否则不要使用 super()。对于您可能怀疑的新型类,这不是通用的“正确的事情”。
有时您期望多重继承并且您可能想要它,但是在您了解 MRO 的毛茸茸的细节之前,最好不要管它并坚持:
X.a(self)
__init__
)以干净且合理的方式传递参数,否则当有人尝试使用您的类进行乘法继承时,您会遇到 TypeError 或更严重的调试问题.除非您真的设计为以这种方式支持 MI(这很棘手),否则最好避免暗示 super
具有该方法是 MI 安全的。
如果以上答案都没有明确提及。您的父类需要从“对象”继承,这实际上会将其变成一个新的样式类。
# 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
我尝试了各种 Xa() 方法;但是,它们似乎需要 X 的实例才能执行 a(),所以我做了 X().a(self),这似乎比以前的答案更完整,至少对于我遇到的应用程序而言。由于存在不必要的构造和破坏,这似乎不是处理问题的好方法,但它工作正常。
我的特定应用程序是 Python 的 cmd.Cmd 模块,由于某种原因,它显然不是 NewStyle 对象。
最后结果:
X().a(self)