In Python 2.5, the following code raises a 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
If I replace the class X
with class X(object)
, it will work. What's the explanation for this?
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)
__init__
) to pass through arguments in a clean and sensible way, otherwise you'll get TypeErrors or worse debugging problems when someone tries to multiply-inherit using your class. Unless you've really designed to support MI in this way (which is quite tricky), it's probably better to avoid the implication super
has that the method is MI-safe.
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
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)
Success story sharing