Как добавить переменную в модуль, из которого я импортирую? - PullRequest
1 голос
/ 14 декабря 2009

Что я хочу сделать, это примерно так:

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 *

А именно, у меня есть шаблонный модуль, который другие модули должны «расширять», добавляя необходимые переменные. Можно ли это сделать функциональным образом (в отличие от наследования объектов)?

РЕДАКТИРОВАТЬ: Добавлено немного больше кода.

Ответы [ 3 ]

4 голосов
/ 14 декабря 2009

Я не уверен, что вы подразумеваете под "функциональным образом" - вы имеете в виду, как в функциональном программировании ? Этого не произойдет (поскольку вы по своей сути пытаетесь изменить объект, что противоположно FP). Или вы имеете в виду что-то вроде «способ, который работает»?

Для последней интерпретации большая проблема - это часть import * - среди множества проблем, которые предлагают не использовать это, вы собираетесь запустить smack в одну: она выполняет снимок независимо от того, какие имена уровня модуля связаны в данный момент (или только те, которые перечислены в __all__ в модуле, если он определен) - будущие изменения в привязках имен никогда не будут отражены в модулях, которые ранее делали import * .

Почему вы считаете, что вам нужно объединить пространство имен template_module с пространством имен импортирующего модуля? Если вы только что выполнили обычный import template_module as tm, то простое обращение ко всем соответствующим именам как tm.this, tm.that будет работать просто отлично (включая получение всех изменений в привязках до момента использования - другими словами , он использует подход с «поздним связыванием», который вам здесь необходим).

0 голосов
/ 15 декабря 2009

Оказывается, это решение ориентировано на ткань.
Таким образом, у вас есть абстрактный some__fab__template.py и конкретный fabfile.py , который должен «расширить» шаблон, добавив некоторые обязательные переменные (например, имя проекта).
Я реализовал это, используя словарь env от fab.
В файле шаблона вы ссылаетесь на env.VAR, а в 'конкретном' fabfile.py вы делаете это:

from fabric.api import *
env.VAR = 'some value'
import some__fab__template

def dist():
    some__fab__template.dist()
0 голосов
/ 14 декабря 2009

Если вы измените свойство модуля в одном месте, оно будет таким же и в других местах. Доказательство:

Создать файл '/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 тоже везде.

...