1

Given the following requirements:

  1. We have the classes Foundation and Data
  2. Data is a child class of Foundation
  3. Instances of Foundation hold an instance of Data

Python code:

from __future__ import annotations

class Foundation():
    data: Data

    def __init__(self):
        self.data = Data()

class Data(Foundation):
    pass

Foundation()

However, the given script exits with an RecursionError. Why and how can I implement the three given requirements?

5t4cktr4c3
  • 151
  • 1
  • 10
  • Apart from that it is not possible what you would like to do, you do realize that you have both a static member `data` and an instance member `data` there, right? – ypnos Jul 23 '20 at 14:29
  • Why `Data` need to inheriting Foundation? This causes a cyclical dependence – Damião Martins Jul 23 '20 at 14:30
  • @DamiãoMartins `Foundation` implements basic features for all my classes. However, `Foundation` may contain `Data`. – 5t4cktr4c3 Jul 23 '20 at 14:33
  • @5t4cktr4c3 This way every time you instantiate a Data, the constructor of the Foundation was called and it call Data constructor and so on. Because that the `RecursionError` happens – Damião Martins Jul 23 '20 at 14:41

1 Answers1

1

You can use super to avoid calling an object that calls an object that calls an object... and so on untill recursion error.

from __future__ import annotations

class Foundation():
    def __init__(self, data):
        self.data = data
        print(self.data)

class Data(Foundation):
    def __init__(self):
        super(Data, self).__init__(self)

Data()

Now you called Data, and data's super is a Foundation, which holds a reference to it's child.

Tutorial

nagyl
  • 1,644
  • 1
  • 7
  • 18
  • What if we have to use `__new__()`, becauase `Foundation` is implemented with it? – 5t4cktr4c3 Jul 23 '20 at 15:05
  • Python's init is the generat initial function. If you would like to use __new__(), or any other funtion, you can access it through super. Implement it the right way. Check python classes for further information! – nagyl Jul 23 '20 at 15:44
  • You can just call `super()`, see https://stackoverflow.com/a/576183/21974 – ypnos Jul 23 '20 at 16:05
  • Thanks for your answer; I solved the problem by checking if the current class (from `__new__()`) is `Data`. If so, `self.data` is not being assigned: `if cls is not Data: instance.data = Data()` – 5t4cktr4c3 Jul 27 '20 at 17:04