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(object)代替 class X,它就会工作。对此有什么解释?

46746 次浏览

The reason is that super() only operates on new-style classes, which in the 2.x series means extending from 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

In addition, don't use super() unless you have to. It's not the general-purpose "right thing" to do with new-style classes that you might suspect.

There are times when you're expecting multiple inheritance and you might possibly want it, but until you know the hairy details of the MRO, best leave it alone and stick to:

 X.a(self)

I tried the various X.a() methods; however, they seem to require an instance of X in order to perform a(), so I did X().a(self), which seems more complete than the previous answers, at least for the applications I've encountered. It doesn't seem to be a good way of handling the problem as there is unnecessary construction and destruction, but it works fine.

My specific application was Python's cmd.Cmd module, which is evidently not a NewStyle object for some reason.

Final Result:

X().a(self)

In case none of the above answers mentioned it clearly. Your parent class needs to inherit from "object", which would essentially turn it into a new style class.

# 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