tags:

views:

869

answers:

5

I'm used that in Objective-C I've got this construct:

- (void)init {
    if (self = [super init]) {
        // init class
    }
    return self;
}

Should Python also call the parent class's implementation for __init__?

class NewClass(SomeOtherClass):
    def __init__(self):
        SomeOtherClass.__init__(self)
        # init class

Is this also true/false for __new__() and __del__()?

Edit: There's a very similar question: Inheritance and Overriding __init__ in Python

+3  A: 

Edit: (after the code change)
There is no way for us to tell you whether you need or not to call your parent's __init__ (or any other function). Inheritance obviously would work without such call. It all depends on the logic of your code: for example, if all your __init__ is done in parent class, you can just skip child-class __init__ altogether.

consider the following example:

>>> class A:
    def __init__(self, val):
     self.a = val


>>> class B(A):
    pass

>>> class C(A):
    def __init__(self, val):
     A.__init__(self, val)
     self.a += val


>>> A(4).a
4
>>> B(5).a
5
>>> C(6).a
12
SilentGhost
I removed the super call from my example, is I wanted to know if one should call the parent class's implementation of __init__ or not.
Georg
you might want to edit the title then. but my answer still stands.
SilentGhost
+3  A: 

There's no hard and fast rule. The documentation for a class should indicate whether subclasses should call the superclass method. Sometimes you want to completely replace superclass behaviour, and at other times augment it - i.e. call your own code before and/or after a superclass call.

Update: The same basic logic applies to any method call. Constructors sometimes need special consideration (as they often set up state which determines behaviour) and destructors because they parallel constructors (e.g. in the allocation of resources, e.g. database connections). But the same might apply, say, to the render() method of a widget.

Further update: What's the OPP? Do you mean OOP? No - a subclass often needs to know something about the design of the superclass. Not the internal implementation details - but the basic contract that the superclass has with its clients (using classes). This does not violate OOP principles in any way. That's why protected is a valid concept in OOP in general (though not, of course, in Python).

Vinay Sajip
What about new and del?
Georg
You said that sometimes one would want to call own code before the superclass call. To do this, one needs knowledge of the parent class's implementation, which would violate the OPP.
Georg
+4  A: 

In Python, calling the super-class' __init__ is optional. If you call it, it is then also optional whether to use the super identifier, or whether to explicitly name the super class:

object.__init__(self)

In case of object, calling the super method is not strictly necessary, since the super method is empty. Same for __del__.

OTOH, for __new__, you should indeed call the super method, and use its return as the newly-created object - unless you explicitly want to return something different.

Martin v. Löwis
So there's no convention to just call super's implementation?
Georg
In old-style classes, you could only call the super __init__ if the super class actually had an __init__ defined (which it often doesn't). Therefore, people typically think about calling super method, rather than doing it out of principle.
Martin v. Löwis
If the syntax in python was as simple as `[super init]`, it would be more common. Just a speculative thought; the super construct in Python 2.x is a bit awkward to me.
kaizer.se
+1  A: 

IMO, you should call it. If your superclass is object, you should not, but in other cases I think it is exceptional not to call it. As already answered by others, it is very convenient if your class doesn't even have to override __init__ itself, for example when it has no (additional) internal state to initialize.

kaizer.se
+3  A: 

If you need something from super's __init__ to be done in addition to what is being done in the current class's __init__, you must call it yourself, since that will not happen automatically. But if you don't need anything from super's __init__, no need to call it. Example:

>>> class C(object):
    def __init__(self):
     self.b = 1


>>> class D(C):
    def __init__(self):
     super().__init__()
     self.a = 1


>>> class E(C):
    def __init__(self):
     self.a = 1


>>> d = D()
>>> d.a
1
>>> d.b  # This works because of the call to super's init
1
>>> e = E()
>>> e.a
1
>>> e.b  # This is going to fail since nothing in E initializes b...
Traceback (most recent call last):
  File "<pyshell#70>", line 1, in <module>
    e.b  # This is going to fail since nothing in E initializes b...
AttributeError: 'E' object has no attribute 'b'

__del__ is the same way, (but be wary of relying on __del__ for finalization - consider doing it via the with statement instead).

I rarely use __new__. I do all the initialization in __init__.

Anon