Как добавить переменную в модуль, из которого я импортирую?
Вопрос
Я хочу сделать что-то вроде этого:
template.py
def dummy_func():
print(VAR)
# more functions like this to follow
fabfile.py
# this gets called by fabric (fabfile.org)
# safe to think of it as ant build.xml
import template
template.VAR = 'some_val'
from template import *
А именно, у меня есть модуль шаблона, который другие модули должны «расширять», добавляя необходимые переменные.Можно ли это сделать функциональным способом (в отличие от наследования объектов)?
РЕДАКТИРОВАТЬ:Добавил еще немного кода.
Решение
Я не уверен, что вы подразумеваете под «функциональным способом» — вы имеете в виду, как в функциональное программирование?Этого не произойдет (поскольку вы по сути пытаетесь изменить объект, что является противоположностью FP).Или вы имеете в виду что-то вроде «способ, который работает»?
Для последней интерпретации большая проблема заключается в import *
часть - среди множества проблем, которые предлагают не использовать это, вы столкнетесь с одной:он выполняет снимок любых имен уровня модуля, связанных в данный момент (или только тех, которые перечислены в __all__
в модуле, если это определено) — будущие изменения привязок имен никогда не будут отражены в модулях, которые ранее выполняли import *
.
Почему вы считаете, что вам необходимо объединить template_module
в пространство имен импортирующего модуля?Если вы только что сделали обычный import template_module as tm
, а затем просто ссылаясь на все соответствующие имена как tm.this
, tm.that
будет работать нормально (включая сбор всех изменений в привязках до момента использования - другими словами, он использует подход «позднего связывания», который вам здесь нужен).
Другие советы
Если вы измените свойство модуля в одном месте, оно будет таким же и в других местах.Доказательство:
Создайте файл «/tmp/test1.py»:
imoprt os
os.path = '' # set os.path (module) to a mere string
os.zzz = 'zzz'
Затем
cd /tmp && python
>>> dir(test)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'os', 'z']
>>> test.os
<module 'os' from '/usr/lib/python2.6/os.pyc'>
>>> test.os.path
''
>>> import os
>>> os.path
''
>>> os.zzz
'zzz'
Теперь os.path — пустая строка даже в основном приложении, а zzz тоже везде.
Оказывается, здесь есть решение, ориентированное на ткань.
Итак, у вас есть реферат some__fab__template.py и бетон fabfile.py это должно «расширить» шаблон, добавив некоторые необходимые переменные (например,название проекта).
Я реализовал это, используя fab окружение словарь.
В файле шаблона, на который вы ссылаетесь env.VAR
и в «бетоне» fabfile.py ты делаешь это:
from fabric.api import *
env.VAR = 'some value'
import some__fab__template
def dist():
some__fab__template.dist()