11

Consider the following code:

class A(object):
    def __init__(self):
        pass
class B(object):
    def __init__(self):
        self.something = 'blue'
    def get_something(self):
        return self.something
class C(A,B):
    def __init__(self):
        super().__init__()
        print(self.get_something())

and then do:

c = C()

which results in something like this:

AttributeError: 'C' object has no attribute 'something'

I suppose this happens due to the constructor of B not being called when using super(). Is there a way to achieve the correct behavior with Python 3?

2 Answers 2

14

Superclasses should use super if their subclasses do. If you add the super().__init__() line into A and B your example should work again.

Check the method resolution order of C:

>>> C.mro()
[__main__.C, __main__.A, __main__.B, builtins.object]

This article should clear things up.

Sign up to request clarification or add additional context in comments.

Comments

4

As others have mentioned, the method resolution order is key here. If you want to call multiple superclass constructors, then you can call them directly.

class A(object):
    def __init__(self):
        pass
class B(object):
    def __init__(self):
        self.something = 'blue'
    def get_something(self):
        return self.something
class C(A,B):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        print(self.get_something())

10 Comments

Your choice. I just wanted to show this option as well, since it is my preference.
This style of multiple inheritance breaks down if your inheritance hierarchy is more complex. For instance, if A and B both inherited from some common Base class (the classic "diamond" pattern) and both called Base.__init__(self) from their own __init__ methods, the Base class would be initialized twice. If you used super instead, each __init__ method would be called exactly once.
Hardcoding the base classes in the subclasses is definitely the wrong way to solve this.
The superclasses are already "hardcoded" into the class definition. Creating a dependence from a superclass to other peers is more damaging in my opinion.
What happens if one of your __init__ methods anywhere takes arguments? Or what if you inherit from a class that exists in a package that you don't maintain?
|

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.