Python super() raises TypeError
Solution 1
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
Solution 2
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)
Solution 3
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
Solution 4
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)
Related videos on Youtube
MarkD
Updated on May 28, 2020Comments
-
MarkD about 4 years
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
withclass X(object)
, it will work. What's the explanation for this?-
AliBZ about 11 yearsyour "however I replace class X with class X(object)" fixed my problem ! thanx
-
sophros over 4 yearsDoes this answer your question? super() fails with error: TypeError "argument 1 must be type, not classobj" when parent does not inherit from object
-
-
MarkD over 15 yearsFrom what python version did this become default behaviour ?
-
Serafina Brocious over 15 years2.2 was when new-style classes were introduced, 3.0 is where they became the default.
-
James Brady over 15 years@tsunami if you want to get at the superclass, do "X.a(self)"
-
MarkD over 15 yearsI think you misunderstood me . Triptych . I remember I was using a python version less than 3.0 , and I didn't specifically said that my class inherits from Object , and the call to super worked . Maybe it's default behaviour from 2.6 ? Just saying :)
-
Serafina Brocious over 15 yearsAlabaster, there's really no need for that. New-style classes have a huge number of benefits, not just super. Old-style ways shouldn't be promoted.
-
Serafina Brocious over 15 yearsTsunami, You're quite likely right. 2.6 is meant as a half-way to 3.0 and it would make sense for them to make it the default there. However, you'll have to check the docs on that.
-
MarkD over 15 yearsThanks for the quick response Cody ! Thanks for the comments guys !
-
philgo20 about 14 yearsis that correct because in my 6 months of Python/Django I've been using super as the "general right thing to do " ?
-
Amit Patil about 14 yearsWell it doesn't hurt you for single inheritance in itself (except that it's a bit slower), but it doesn't get you anything on its own either. You have to design any methods that need to multiply-inherit (most notably
__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 implicationsuper
has that the method is MI-safe. -
sophros over 4 yearsSorry, but in Python 3.x your second example (implicit inheritance) does not really work in the context of the issue mentioned.
-
Boris Verkhovskiy about 3 yearsThis seems like bad advice.