The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.
All methods that are called with super() need to have a call to their superclass's version of that method. This means that you will need to add super(). __init__() to the . __init__() methods of Triangle and Rectangle .
Use super(). __init()__ to call the immediate parent class constructor in Python. Calling a parent constructor within a child class executes the operations of the parent class constructor in the child class.
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__() # in Python 2 use super(D, self).__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__.
In Anon's answer:
"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"
It's incredible: he is wording exactly the contrary of the principle of inheritance.
It is not that "something from super's __init__
(...) will not happen automatically" , it is that it WOULD happen automatically, but it doesn't happen because the base-class' __init__
is overriden by the definition of the derived-clas __init__
So then, WHY defining a derived_class' __init__
, since it overrides what is aimed at when someone resorts to inheritance ??
It's because one needs to define something that is NOT done in the base-class' __init__
, and the only possibility to obtain that is to put its execution in a derived-class' __init__
function.
In other words, one needs something in base-class' __init__
in addition to what would be automatically done in the base-classe' __init__
if this latter wasn't overriden.
NOT the contrary.
Then, the problem is that the desired instructions present in the base-class' __init__
are no more activated at the moment of instantiation. In order to offset this inactivation, something special is required: calling explicitly the base-class' __init__
, in order to KEEP , NOT TO ADD, the initialization performed by the base-class' __init__
.
That's exactly what is said in the official doc:
An overriding method in a derived class may in fact want to extend rather than simply replace the base class method of the same name. There is a simple way to call the base class method directly: just call BaseClassName.methodname(self, arguments).
http://docs.python.org/tutorial/classes.html#inheritance
That's all the story:
when the aim is to KEEP the initialization performed by the base-class, that is pure inheritance, nothing special is needed, one must just avoid to define an __init__
function in the derived class
when the aim is to REPLACE the initialization performed by the base-class, __init__
must be defined in the derived-class
when the aim is to ADD processes to the initialization performed by the base-class, a derived-class' __init__
must be defined , comprising an explicit call to the base-class __init__
What I feel astonishing in the post of Anon is not only that he expresses the contrary of the inheritance theory, but that there have been 5 guys passing by that upvoted without turning a hair, and moreover there have been nobody to react in 2 years in a thread whose interesting subject must be read relatively often.
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__
.
On the other hand, 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.
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
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).
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.
Yes, you should always call base class __init__
explicitly as a good coding practice. Forgetting to do this can cause subtle issues or run time errors. This is true even if __init__
doesn't take any parameters. This is unlike other languages where compiler would implicitly call base class constructor for you. Python doesn't do that!
The main reason for always calling base class _init__
is that base class may typically create member variable and initialize them to defaults. So if you don't call base class init, none of that code would be executed and you would end up with base class that has no member variables.
Example:
class Base:
def __init__(self):
print('base init')
class Derived1(Base):
def __init__(self):
print('derived1 init')
class Derived2(Base):
def __init__(self):
super(Derived2, self).__init__()
print('derived2 init')
print('Creating Derived1...')
d1 = Derived1()
print('Creating Derived2...')
d2 = Derived2()
This prints..
Creating Derived1...
derived1 init
Creating Derived2...
base init
derived2 init
Run this code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With