Parent constructor called by default?
<p>I have the following example from python <code>page_object</code> docs:</p>

<pre><code> from page_objects import PageObject, PageElement
 from selenium import webdriver

 class LoginPage(PageObject):
        username = PageElement(id_='username')
        password = PageElement(name='password')
        login = PageElement(css='input[type="submit"]')

 driver = webdriver.PhantomJS()
 driver.get("http://example.com")
 page = LoginPage(driver)
 page.username = 'secret'
 page.password = 'squirrel'
 assert page.username.text == 'secret'
 page.login.click()
</code></pre>

<p>What bothers me is that we create a <code>LoginPage</code> with providing a <code>driver</code> to it's constructor, but we haven't define a <code>__init__</code> method in <code>LoginPage</code> class. </p>

<p>Does that mean that the parent class <code>PageObject</code>'s constructor is called with <code>driver</code> parameter? I thought that python doesn't implicitly call parent's constructors?</p>

<p>The <code>__init__</code> method is just a method and as such python performs the same kind of lookup for it as other methods. If class <code>B</code> does not define a method/attribute <code>x</code> then python looks up it's base class <code>A</code> and so on, until it either finds the attribute/method or fails.</p>

<p>A simple example:</p>

<pre><code>&gt;&gt;&gt; class A:
...     def method(self):
...         print('A')
... 
&gt;&gt;&gt; class B(A): pass
... 
&gt;&gt;&gt; class C(B):
...     def method(self):
...         print('C')
... 
&gt;&gt;&gt; a = A()
&gt;&gt;&gt; b = B()
&gt;&gt;&gt; c = C()
&gt;&gt;&gt; a.method()
A
&gt;&gt;&gt; b.method()  # doesn't find B.method, and so uses A.method
A
&gt;&gt;&gt; c.method()
C
</code></pre>

<p>The same is with <code>__init__</code>: since <code>LoginPage</code> does not define <code>__init__</code> python looks up the <code>PageObject</code> class and finds its definition there.</p>

<p>What is meant when we say that "python doesn't implicitly call parent class constructors" is that <strong>if you define an <code>__init__</code> method</strong> the interpreter will just call that method and <em>not</em> call all the parent class <code>__init__</code>s, and as such if you want to call the parent class constructor you have to do so explicitly.</p>

<p>Note the difference among these classes:</p>

<pre><code>&gt;&gt;&gt; class A:
...     def __init__(self):
...         print('A')
... 
&gt;&gt;&gt; class B(A):
...     pass
... 
&gt;&gt;&gt; class B2(A):
...     def __init__(self):
...         print('B')
... 
&gt;&gt;&gt; class B3(A):
...     def __init__(self):
...         print('B3')
...         super().__init__()
... 
&gt;&gt;&gt; A()
A
&lt;__main__.A object at 0x7f5193267eb8&gt;
&gt;&gt;&gt; B()  # B.__init__ does not exists, uses A.__init__
A
&lt;__main__.B object at 0x7f5193267ef0&gt;
&gt;&gt;&gt; B2()  # B2.__init__ exists, no call to A.__init__
B
&lt;__main__.B2 object at 0x7f5193267eb8&gt;
&gt;&gt;&gt; B3()  # B3.__init__exists, and calls to A.__init__ too
B3
A
&lt;__main__.B3 object at 0x7f5193267ef0&gt;
</code></pre>

python oop selenium selenium-webdriver