Comment ajouter une variable au module I importer à partir?
Question
Ce que je veux faire est quelque chose comme ceci:
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 *
A savoir que j'ai un module de modèle d'autres modules devraient « étendre » les variables contribuant nécessaires. Cela peut-il être fait d'une manière fonctionnelle (par opposition à l'héritage objet)?
EDIT:. Ajout d'un peu plus de code
La solution
Je ne sais pas ce que vous entendez par « une manière fonctionnelle » - voulez-vous dire, comme dans programmation fonctionnelle ? Cela ne va pas se produire (puisque vous êtes intrinsèquement essayer de modifier un objet, qui est l'inverse de la FP). Ou voulez-vous dire quelque chose comme « une manière qui fonctionne »?
Pour cette dernière interprétation, le gros problème est la partie import *
- parmi les nombreux problèmes qui n'utilisent pas que suggèrent, vous allez être en cours d'exécution smack en une seule: il effectue un instantané quel que soit les noms de niveau module sont liés au moment (ou seulement celles qui sont énumérées dans __all__
dans le module, si cela est défini) -. futurs changements aux fixations des noms ne seront jamais pris en compte dans les modules qui auparavant le import *
Pourquoi croyez-vous que vous avez besoin de fusionner l'espace de noms du template_module
dans celui du module importateur? Si vous venez de faire une import template_module as tm
régulière, se contentant de mentionner tous les noms pertinents que tm.this
, tm.that
fonctionnera très bien (y compris ramasser toutes les modifications apportées aux liaisons jusqu'à l'instant d'utilisation - en d'autres termes, il utilise la « fin contraignant » approche que vous semblez avoir besoin ici).
Autres conseils
Si vous modifiez une propriété d'un module en un seul endroit, ce sera la même chose dans d'autres endroits aussi. Preuve:
Créer un fichier '/tmp/test1.py':
imoprt os
os.path = '' # set os.path (module) to a mere string
os.zzz = 'zzz'
Ensuite
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'
Il est maintenant os.path une chaîne vide, même dans l'application principale, et zzz est partout aussi.
Il s'avère que cela a une solution de tissu centrée.
Vous avez donc un résumé some__fab__template.py et un béton fabfile.py qui devrait 'étendre' le modèle contribuant certaines variables nécessaires (par exemple le nom du projet).
Je l'ai implémenté en utilisant des années fab env dictionnaire.
Dans le fichier de modèle que vous faites référence à env.VAR
et dans le 'concret' fabfile.py vous faites ceci:
from fabric.api import *
env.VAR = 'some value'
import some__fab__template
def dist():
some__fab__template.dist()