Как правильно разделить аргумент командной строки между несколькими классами, которые инициализируют друг друга в Python - PullRequest
0 голосов
/ 28 августа 2018

Моя структура проекта следующая

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

, где run.py инициализирует объект ClassA, что, в свою очередь, инициализирует объект ClassB.

Теперь run.py также анализирует аргумент командной строки, указывающий на файл config.yaml. Словарь, полученный в результате синтаксического анализа этого файла .yaml, содержит ключи и значения, необходимые для ClassA и ClassB при их инициализации.

У меня такой вопрос: как мне лучше всего использовать этот аргумент командной строки для обоих классов?

Очевидным решением было бы передать его в метод __init__ из ClassA и передать ему словарь config в метод __init__ из ClassB; но это кажется нелегким, потому что тогда аргумент будет передан как водопад. Я бы предпочел получить доступ к аргументу командной строки из каждого класса при его создании, не передавая его методу __init__ повторно в качестве аргумента.

Правильно ли я считаю, что передача аргумента через несколько уровней не является хорошим дизайном? Если так, что может быть лучшим решением?

1 Ответ

0 голосов
/ 28 августа 2018

Ну, на мой взгляд, это приемлемый и относительно элегантный способ (если вы передаете в ClassB только соответствующую часть данных).

Я могу придумать несколько других способов:

  • Имеют общий класс настроек, который инициализируется первым в run.py, и ClassA и ClassB получают свои настройки из него. - В этом случае ClassA и ClassB нужна ссылка на этот класс - мало чем отличается от вашего решения. Вы бы передавали класс вместо словаря.
  • Иметь класс или функцию, которая считывает данные из файла конфигурации по мере необходимости. Вы могли бы даже иметь базовый класс, реализующий эту функциональность, и заставить ClassA и ClassB наследовать его. Это может работать как своего рода «десериализуемый» интерфейс. ( В Python нет интерфейсов )
  • Вы можете сделать так, чтобы ваш run.py инициализировал ClassA и ClassB и вставлял ссылку ClassB на ClassA (либо конструктор, либо свойство).
  • Вы можете использовать глобальные переменные , но это не элегантно и опасно.
...