Я хотел бы определить вспомогательную функцию, которая имеет возможность модифицировать переменную уровня модуля (с известным именем) из окружающего контекста, не передавая ее явно, например.Как получить переменную модуля в функции из другого модуля?
# mod1.py
mod_var = 1
modify_var()
# mod_var modified
print mod_var
Проблема в том, - я не могу ссылаться на переменную mod1.mod_var
, потому что я хочу использовать вспомогательную функцию во многих модулях (сам помощник будет определен в другом модуле); он должен динамически «выбирать» mod_var из окружающего контекста/области вызова.
Возможно ли это? Как это получить?
Моим вариантом использования является улучшение определения URL -> отображения отображения в Django. Эти определения распределены по многим подмодулям, которые определяют переменную уровня модуля urlpatterns
. Функция помощника должна выбрать эту переменную из модуля, который ее вызывает и модифицирует. Избежать явного передачи его в качестве аргумента было бы здорово.
Редактировать: Для дополнительного решения - отметьте this ответ.
Edit2:
Неправильное решение ниже! (слева для ссылок в комментариях)
Недавно я нашел другое решение (наименее волшебный, на мой взгляд;)) modify_var()
функция может быть реализована следующим образом:
def modify_var():
calling_module = __import__("__main__")
calling_module.mod_var = 42
Тем не менее, потенциальные прибыли спорно.
unittest
модуль использует эту технику в своем методе main
.
У моего решения от 2-го редактирования (в вопросе) есть достаточно низкий уровень магии? ;) По-прежнему существует проблема с отсутствием объяснения. – gorsky
@gorsky, ваше второе решение (которое является достаточно явным и не магическим) не делает ничего даже ** близко ** к тому, что вы говорите в своем Q, которое вы хотите сделать: оно всегда изменяет var в главном модуле , ** не ** в вызывающем модуле! Просто попробуйте с помощью модулей 'a' и' b', которые я покажу в своем ответе, если это не совсем очевидно для вас. –
Вы правы - я протестировал это неправильно: называть его как 'python a.py' делает' a.py' основным модулем, тем самым работая так, как я хотел. Неправильное предположение, спасибо, что помогли мне это сделать. – gorsky