Search code examples
pythonpython-2.7oopinheritancemultiple-inheritance

ChildClass object has no attribute bar


class Foo(Baz, Qux):
    def __init__(self, bar, *args, **kwargs):
        super(Foo, self).__init__(bar=bar, *args, **kwargs)

class Baz:   
    def __init__(self, bar, *args, **kwargs):
        self.bar = bar

This is the structure of my classes with the Foo class inheriting the Baz class. However when I try running the code, I get the following error Foo object has no attribute bar

From what I understand, the super(childclass, self).__init__(parent, attributes) should initialize the parent class as well. Why should bar be present in the child class too?

I followed the following stack answers to implement this: Calling parent class __init__ with multiple inheritance, what's the right way?

EDIT

class Qux:   
    def __init__(self, xyz, *args, **kwargs):
        self.xyz = xyz
    
    def print_barqux(self):
        print(self.xyz)
        
class Baz:   
    def __init__(self, bar, *args, **kwargs):
        self.bar = bar
        
class Foo(Baz, Qux):
    def __init__(self, bar, xyz, *args, **kwargs):
        super(Foo, self).__init__(bar=bar, xyz=xyz)

    def printbar(self):
        super(Foo, self).print_barqux()
        
        
foo = Foo(bar="abcd", xyz="abcdef")
print(foo.printbar())

Output:

Traceback (most recent call last):
  File "./prog.py", line 21, in <module>
  File "./prog.py", line 17, in printbar
  File "./prog.py", line 6, in print_barqux
AttributeError: 'Foo' object has no attribute 'xyz'

Adding the error stacktrace with code


Solution

  • Every class has to call super.__init__:

    class Qux:   
        def __init__(self, xyz, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.xyz = xyz
        
        def print_barqux(self):
            print(self.xyz)
            
    class Baz:   
        def __init__(self, bar, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.bar = bar
            
    class Foo(Baz, Qux):
        def __init__(self, bar, xyz, *args, **kwargs):
            super().__init__(bar=bar, xyz=xyz)
    
        def printbar(self):
            super().print_barqux()
            
            
    foo = Foo(bar="abcd", xyz="abcdef")
    print(foo.printbar())