python __init__ method in inherited class

36,673

Solution 1

As far as I know that's not possible, however you can call the init method of the superclass, like this:

class inheritedclass(initialclass):
    def __init__(self):
        initialclass.__init__(self)
        self.attr3 = 'three'

Solution 2

Just call the parent's __init__ using super:

class inheritedclass(initialclass):
    def __new__(self):
        self.attr3 = 'three'
        super(initialclass, self).__init__()

I strongly advise to follow Python's naming conventions and start a class with a Capital letter, e.g. InheritedClass and InitialClass. This helps quickly distinguish classes from methods and variables.

Solution 3

First of all you're mixing __init__ and __new__, they are different things. __new__ doesn't take instance (self) as argument, it takes class (cls). As for the main part of your question, what you have to do is use super to invoke superclass' __init__.

Your code should look like this:

class initialclass(object):
    def __init__(self):
        self.attr1 = 'one'
        self.attr2 = 'two'    

class inheritedclass(initialclass):
    def __init__(self):
        self.attr3 = 'three'
        super(inheritedclass, self).__init__()

Solution 4

It's incredibly simple. Define a new __init__ method and call the parent's __init__ at the beginning.

# assuming a class Base, its __init__ takes one parameter x

class Derived(Base):
    def __init__(self, x, y):
        # whatever initialization is needed so we can say Derived is-a Base
        super(Derived, self).__init__(x)
        # now, add whatever makes Derived special - do your own initialization
        self.y = y

In Python 3, you don't have to (and therefore propably shouldn't, for simplicity) explicitly inherit from object or pass the class and self to super.

Share:
36,673

Related videos on Youtube

Anake
Author by

Anake

Updated on December 10, 2020

Comments

  • Anake
    Anake over 3 years

    I would like to give a daughter class some extra attributes without having to explicitly call a new method. So is there a way of giving the inherited class an __init__ type method which does not override the __init__ method of the parent class?

    I have written the code below purely to illustrate my question (hence the poor naming of attributes etc).

    class initialclass():
        def __init__(self):
            self.attr1 = 'one'
            self.attr2 = 'two'    
    
    class inheritedclass(initialclass):
        def __new__(self):
            self.attr3 = 'three'
    
        def somemethod(self):
            print 'the method'
    
    
    a = inheritedclass()
    
    for each in a.__dict__:
        print each
    
    #I would like the output to be:
    attr1
    attr2
    attr3
    

    Thank you

    • khachik
      khachik about 13 years
      Call initialclass.__init__ in the derived class constructor. However, the order of attrX is not guaranteed.
    • Admin
      Admin about 13 years
      Do not override __new__ unless you know exactly what it does and why you need to fiddle with it. You propably don't know. It's not another name for __init__. It's three levels more magic than one us usually concerned with, especially beginners.
    • Lauritz V. Thaulow
      Lauritz V. Thaulow about 13 years
      Note that the argument to __new__ is the class of self, not self, as it's an implicit class method. So in your example you're actually setting the class attribute inheritedclass.attr3, not self.attr3 as you thought.
  • Admin
    Admin about 13 years
    Specifically, use super(DerivingClass, self).__init__(). Or just super().__init__() in Python 3. Edit: -1 because 1. super needs the inheriting(!) class and 2. you override __new__ needlessly, and the code as of now is in fact incorrect (it creates a class attribute attr3).
  • Admin
    Admin about 13 years
    Virtual -1. No need to do any extra work, let alone hasattr and extra methods, in the parent class. You can simply define a new __init__ that calls the parent's __init__ using super.
  • Anake
    Anake about 13 years
    this works with the new method but as lazyr told me (correctly) that I shouldn't use new, I think the correct answer for me yexo's. Thanks though!
  • Lauritz V. Thaulow
    Lauritz V. Thaulow about 13 years
    @delnan I know this, but the question was "is there a way of giving the inherited class an init type method which does not override the init method of the parent class". I've provided such a way. This has the added benefit of giving an entrypoint to calling only the subclass init from some other subclass method.
  • Admin
    Admin about 13 years
    That's why it's virtual. I know it's what OP asked for, but OP asked "How do I use a hammer to do this?" and the answer is "You use a screwdriver".
  • Anake
    Anake about 13 years
    thanks,my mistake about the new method. I am trying to use super and I keep getting this error: TypeError: super() argument 1 must be type, not classobj. (I copied and pasted you code exactly as well)
  • Admin
    Admin about 13 years
    @Anake: initialclass needs to inherit object (class initialclass(object)), otherwise it's an old-style class, which is little more than a headache-inducing relic from the past and should be avoided.
  • Lauritz V. Thaulow
    Lauritz V. Thaulow about 13 years
    @delnan What I thought OP asked was, to borrow your anology, "How do I use a hammer to do this when I don't want to use a screwdriver?". I assumed overriding included extending, since to my mind an extended method is simply a type of overridden method -- one that calls the parent method somehow. I assumed, wrongly it seems, he knew how to extend a method. By the way, aren't all python methods virtual? I've never heard anyone talk about virtual methods in python.
  • Admin
    Admin about 13 years
    You're correct about Python methods being virtual, the -1 is virtual ;)
  • Lauritz V. Thaulow
    Lauritz V. Thaulow about 13 years
    @Anake Credit where credit is due, it was @delnan who told you not to use __new__, I just explained what your code actually did. By the way, __new__ must return an instance of its class if you implement it. In the above answer, and in your code too, inheritedclass() is None! In other words, it doesn't work at all. (I mistakenly gave this answer an upvote, didn't read the code properly, and now I can't change it :(.)
  • qwwqwwq
    qwwqwwq over 10 years
    brilliant, ive been trying to figure out a good way to handle this case for awhile
  • Mohsin Bukhari
    Mohsin Bukhari about 6 years
    are there any downsides to this?