tags:

views:

1451

answers:

2

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 "", line 1, in 
  File "", line 3, in a
TypeError: super() argument 1 must be type, not classobj

If , however I replace class X with class X(object) , the same code will work . I am using python 2.5.2 .What's the explanation for this ?

+14  A: 

The reason is that super() only operates on new-style classes, which in the 2.x series means extending from object.

Cody Brocious
From what python version did this become default behaviour ?
Geo
@tsunami: version 2.2
Triptych
2.2 was when new-style classes were introduced, 3.0 is where they became the default.
Cody Brocious
@tsunami if you want to get at the superclass, do "X.a(self)"
Alabaster Codify
I 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 :)
Geo
Alabaster, 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.
Cody Brocious
Or maybe I was wrong ... don't remember .
Geo
Tsunami, 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.
Cody Brocious
Thanks for the quick response Cody ! Thanks for the comments guys !
Geo
+2  A: 

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)
bobince
is that correct because in my 6 months of Python/Django I've been using super as the "general right thing to do " ?
PhilGo20
Well 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 implication `super` has that the method is MI-safe.
bobince