1

This is probably very simple question. In a child class, which is inherited from two parent classes, I can't access variable from second parent class using super(). Here is my code:

class Core:
    def __init__(self):
        self.a_from_Core = 7


class Extra:
    def __init__(self):
        self.b_from_Extra = 90


class Trash(Core, Extra):
    def __init__(self):
        super().__init__()

        print(self.a_from_Core)     # working
        print(self.b_from_Extra)    # does not work



trashcan = Trash()

And here is error:

AttributeError: 'Trash' object has no attribute 'b_from_Extra'

What am I doing wrong?

Scott
  • 4,974
  • 6
  • 35
  • 62
  • Does this answer your question? [How does Python's super() work with multiple inheritance?](https://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple-inheritance) – Papipoulpe Feb 09 '23 at 06:57

2 Answers2

1

Python uses "cooperative" multiple inheritance (https://rhettinger.wordpress.com/2011/05/26/super-considered-super/)

which kinda means all classes involved in the inheritance need to agree to play.

For single inheritance, it just works -- which is what lulled you into thinking it would work for multiple.

You need to add calls to super().__init__() in all classes, for example

class Core:
  def __init__(self):
    self.a_from_Core = 7
    super().__init__()  # added


class Extra:
  def __init__(self):
    self.b_from_Extra = 90
    super().__init__()  # added

class Trash(Core, Extra):
  def __init__(self):
    super().__init__()

    print(self.a_from_Core)
    print(self.b_from_Extra)    # works!                                                                                                 

trashcan = Trash()
pbuck
  • 4,291
  • 2
  • 24
  • 36
0

You are inheriting from two classes, according to MRO, your first father is Core and your second father is Extra.

So when you call super, the __init__ in Core is called and the __init__ in the Extra is not called, so you don't have b_from_Extra.

As in MRO of Trash you have something like: [..., Core, Extra], if you call super in Core, the method in Extra would be called.

So you can do the following :

class Core:
  def __init__(self):
    self.a_from_Core = 7
    super().__init__()
...

You can read about MRO.

Amin
  • 2,605
  • 2
  • 7
  • 15