9

I'm trying something very basic with Python inheritance:

class Parent:
    def __init__(self):
        self.text = 'parent'

    def getText(self):
        print self.text

class Child1(Parent):
    def __init__(self):
        self.x = 'x'

class Child2(Parent):
    def __init__(self):
        self.x = 'x'

if __name__ == "__main__": 
    parent = Parent()
    child1 = Child1()
    child2 = Child2()

    parent.getText()
    child1.getText()
    child2.getText()

but I keep getting

Child1 instance has no attribute 'text'

how are variables passed to children?

6
  • You need to call the constructor of the parent classes manually - Here, self.text is initialize in Parent constructor which is never called. Commented Mar 3, 2016 at 15:50
  • @Holt what would that be? super().__init__() ? Commented Mar 3, 2016 at 15:51
  • 2
    @Abdul I misread. For that purpose you should just use pass, that's what it's for (a dummy body). Commented Mar 3, 2016 at 15:53
  • 1
    If you don't want python complaining about empty block, use pass, e.g. if a: pass (only for demonstration purpose). Commented Mar 3, 2016 at 15:54
  • 2
    In addition to pass, if the block is also a function, then adding a docstring also works to prevent python from complaining about the indentation being wrong. Commented Mar 3, 2016 at 16:03

4 Answers 4

11

You need to call the constructor of the parent classes manually - Here, self.text is initialize in Parent constructor which is never called:

class Child1(Parent):
    def __init__ (self):
        super(Child1, self).__init__ ()
        # or Parent.__init__ (self)
        self.x = 'x'
Sign up to request clarification or add additional context in comments.

4 Comments

any reason why I would use super vs Parent init?
@AbdulAhmad There are multiple posts on SO about this: stackoverflow.com/questions/222877/how-to-use-super-in-python, stackoverflow.com/questions/576169/…. I personally use super most of the time.
one more question, what's the correct way of altering the self.text from parent in a child? just self.text = 'new text'? or is there another way more suited for inheritance? (I will accept the answer once the timer is down, have 2 minutes left)
@AbdulAhmad You're just setting an attribute on the self object, it's no different than altering it in another method of the object. Just assign a new value to it.
2

Since python 3.6, we can now use the __init_subclass__ function, which is called automatically before __init__ of the Child.

class Parent:
    def __init__(self):
        self.text = 'parent'
    
    def __init_subclass__(self):
        Parent.__init__(self)

    def getText(self):
        print(self.text)

class Child1(Parent): pass
class Child2(Parent): pass

classes = [Parent(), Child1(), Child2()]

for item in classes:
    item.getText()

output

parent
parent
parent

If you use your Parent class more as a "interface", here is another example.

class Animal():
    def __init_subclass__(self, sound):
        self.sound = sound

    def make_sound(self):
        print(self.sound)

class Cat(Animal, sound='meow'): pass
class Dog(Animal, sound='woof'): pass

animals = [Cat(), Dog()]

for animal in animals:
    animal.make_sound()

output

meow
woof

Comments

1

your init function needs to call the parent init

class Child1(Parent):
def __init__(self):
    self.x = 'x'
    Parent.__init__(self)

Comments

1

In python when you override a function which was supposed to be inherited you override all of it, __init__ is no exception. You should call the functions super method to use the base initializer, or implement the attribute in the constructor you have rewrote.

class Parent:
    def __init__(self):
        self.text = 'parent'

    def getText(self):
        print self.text

class Child1(Parent):
    def __init__(self):
        super(Child1, self).__init__()
        self.x = 'x'

child1.getText()

Should work now.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.