I find this syntax astoundingly annoying. Every time I rename my class, I have to change this call for no apparent reason. Isn't there some __class__
magic variable or something I can use at least? Interested in answers for Python 2.5, but it doesn't hurt to know if later versions fixed this.
views:
113answers:
6
+3
A:
As far as I know, this isn't possible in 2.5. However, in 3.0, this was changed so that you can simply call super().__init__()
.
Justin Ardini
2010-03-28 23:39:16
+2
A:
This is fixed in Python 3. http://docs.python.org/py3k/library/functions.html#super
S.Lott
2010-03-28 23:41:28
+1
A:
I think if your class only inherits from one class it is safe to do just this:
class B(A):
def __init__(self):
A.__init__(self)
But I could be mistaken.
Felix Kling
2010-03-28 23:46:29
No mistake -- that's how it's always worked.
Alex Martelli
2010-03-28 23:53:23
Oh.. well that's not nearly as bad! Why wouldn't this work when it inherits from more than one class? You're explicitly telling it which one you want to use...
Mark
2010-03-29 00:45:01
@Mark: Yeah well of course you can explicitly list every class that your class inherits from. But I don't know how `super()` works internally so maybe it does some sophisticated stuff to initialize everything in the right order. I was more thinking of the fact that you should use `super()` to call any parents method as it makes sure that the right method is called if the class inherits from more than one class. That's why I wrote *safe* as I am definitely sure about this with one class but not about how it behaves with more classes.
Felix Kling
2010-03-29 00:49:25
If your class only inherits from one class and you do this, *your* class will work fine. This doesn't mean that classes later on that *inherit your class* will work fine. `super` is the more general solution.
Mike Graham
2010-03-29 03:32:15
@Mark, imagine you also make `class C(A)` then `class D(B, C)`. How do you write `D.__init__` such that everyone's `__init__` is called exactly once?
Mike Graham
2010-03-29 03:33:37
@Mike: Hrm..? First B would be initialized, then C, then A, then ... oh, I see the problem now :D I don't think I've ever really had a need for multiple inheritance anyway.
Mark
2010-03-29 05:16:07
Why the downvote?
Felix Kling
2010-03-29 06:55:00
@Mark, you don't need actually to use MI to avoid making your classes needlessly rigid.
Mike Graham
2010-03-29 06:58:59
A:
EDIT
As pointed out by Alex, this is wrong where there is more than a single level of inheritence.
Yes, "new" style classes have a __class__
attribute available which can be used, eg.
class B(object):
def __init__(self):
print "B.__init__():"
class D(B):
def __init__(self):
print "D.__init__():"
super(self.__class__, self).__init__()
>>> d = D()
D.__init__():
B.__init__():
>>> dir(d)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
>>> d.__class__
<class '__main__.D'>
mhawke
2010-03-28 23:49:10
**wrong**! Add a `class E(D): pass` and try doing `e = E()`: you get a `maximum recursion depth exceeded` exception because `D.__init__` is calling itself (`self.__class__` is `E` so its `super` is `D` --> infinine recursion).
Alex Martelli
2010-03-28 23:55:58
A:
There is some __class__
magic variable. The __class__
magic variable. Try:
class foo(OtherClass):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
intractelicious
2010-03-29 04:39:40
This is wrong; it won't work. I don't think you understand how `super` works.
Mike Graham
2010-03-29 05:13:15
This does work; though not in the cases mentioned below by Alex Martinelli. However, if OtherClass doesn't call super in this way, it does work (try it!).
intractelicious
2010-03-29 23:24:08