#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
это не будет установлено в основной программе до того, как где-либо понадобится фактическая страна, у вас все должно быть в порядке. Возможно, вы захотите добавить значение по умолчанию, а также сохранить его в базе данных, если сеансы являются постоянными.