tags:

views:

113

answers:

6

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.

+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
+1  A: 

In Python 3.0, the super() can be called without arguments to do the same thing.

Ber
+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
No mistake -- that's how it's always worked.
Alex Martelli
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
@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
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
@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
@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
Why the downvote?
Felix Kling
@Mark, you don't need actually to use MI to avoid making your classes needlessly rigid.
Mike Graham
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
**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
@Alex Martelli: Sounds reasonable.
Felix Kling
Yes, thanks for that. I just noticed that myself too.
mhawke
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
This is wrong; it won't work. I don't think you understand how `super` works.
Mike Graham
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