0

My project structure is the following

|-- project/
   |-- run.py
   |-- classes/
      |-- module_defining_class_a.py [=> class classA():...]
      |-- module_defining_class_b.py [=> class classB():...]
   |-- config.yaml

where run.py initializes a ClassA object, which in turn initializes a ClassB object.

Now run.py also parses a command line argument pointing to a config.yaml file. The dictionary that results from parsing this .yaml file contains keys and values that are required by both ClassA and ClassB when they are initialized.

My question is: How can I best share this command line argument across both classes?

The obvious solution would be to pass it to the __init__ method of ClassA and have it pass the config dictionary on to the __init__ method of ClassB; but this feels unelegant because the argument would then be passed down in a waterfall-like manner. I would much rather be able to access the command line argument from within each class when instantiating it, without passing it to the __init__ method repeatedly as an argument.

Am I correct in assuming that passing the argument down via multiple levels is not good design? If so, what could be a better solution?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Constantin
  • 629
  • 1
  • 7
  • 22

1 Answers1

1

Well, in my opinion it is an acceptable, and relatively elegant way (if you are passing down to ClassB only the relevant part of the data).

I can think of a few other ways:

  • Have a common settings class, which is initialized first in run.py, and both ClassA and ClassB are getting their settings from it. - In this case ClassA and ClassB need a reference to this class - does not differ much from your solution. You would be passing down a class, instead of a dictionary.
  • Have a class or function, which reads in the data from the config file as needed. You could even have a base class implement this functionality, and make ClassA and ClassB inherit from it. It could work as a kind of "Deserializable" interface. (There are no interfaces in python)
  • You could have your run.py initialize ClassA and ClassB, and inject the ClassB reference to ClassA (either constructor or property).
  • You could use global variables, but that is not elegant, and dangerous.
G. B.
  • 528
  • 2
  • 15