Как использовать внедрение зависимостей для внедрения объекта в модуль?

#python #dependency-injection #module

#питон #внедрение зависимостей #модуль

Вопрос:

Это мой сценарий. У меня есть пакет, который состоит из нескольких модулей. Все они импортируются из settings.py . Однако некоторые переменные зависят от пользовательского ввода.

 ...
# some CONSTANTS
...
PROJECT_DIR = Path(os.path.abspath(__file__)).parent.ancestor(1)
SCRIPT_DIR = PROJECT_DIR.child('scripts')
data_input = DATA_ROOT.child('input')
input_root = data_input.child(options.root_input) # the options object holds some user input

# then use input_root to get an instance of class Countries
from countries import Countries
country_object = Countries(input_root)
 

существует несколько модулей, которым требуется country_object . Так что импорт их оттуда settings был бы самым чистым решением.

Итак, я кое-что прочитал dependency injection и думаю, что это то, что здесь пригодится. Но мне трудно обернуть это так, как можно было бы использовать внедрение зависимостей для внедрения объекта options в модуль?

Ответ №1:

Когда дело доходит до шаблонов, есть две философии: подгоните вашу проблему под шаблон и подгоните шаблон под вашу проблему. Я следую последнему. Так что это будет моя адаптация dependency injection шаблона к вашей проблеме:

 class UserCountry(object):
     def __init__(self):be populated by user data
         self.Country = None

     def set_input_root(self, input_root):
         self.input_root = input_root # <-- this is a list/dict etc that I assume will 

     def __call__(self):
         if self.Country:
             return self.Country
         else:
             # Select country
             self.Country = Country
             return self.Country
 

в settings.py :

  user_country = UserCountries()
 

когда input_root определяется:

 settings.user_country.set_input_root(input_root) 
 

в других модулях:

  settings.user_country() # gives you the Country object
 

Комментарии:

1. Но settings.py ничего не знает о. input_root Поэтому я не могу позвонить UserCountries() из настроек. Я мог бы вызвать его из своей основной программы, но проблема остается, поскольку другие модули также не знают о root_input .

2. итак, когда установлен input_root?

3. @LarsVegas Я обновил свой ответ, но вы понимаете, что вы не будете знать input_root, прежде чем узнаете корень ввода…

4. это зависит от пользовательского ввода, поэтому при вызове основной программы. Но основная программа уже импортирует данные из настроек. Другие модули, отличные от основной программы, также будут импортировать настройки. Модуль может использовать другой модуль пакета, а также вне основной программы. Таким образом, input_root и country-instance должны быть действительными и доступными глобально во время выполнения основной программы.

5. Вы видели мою обновленную версию? До тех пор, пока set_input_root это не будет установлено в основной программе до того, как где-либо понадобится фактическая страна, у вас все должно быть в порядке. Возможно, вы захотите добавить значение по умолчанию, а также сохранить его в базе данных, если сеансы являются постоянными.