Wie aus einer Variablen an das Modul I Import hinzufügen?
Frage
Was will ich ist, etwas zu tun wie folgt aus:
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 *
Und zwar habe ich einen Template-Modul andere Module erweitern 'sollen die erforderlichen Variablen beitragen. Kann dies in funktioneller Weise durchgeführt werden (im Gegensatz zu Objektvererbung Gegensatz)?
EDIT:. Hinzugefügt etwas mehr Code
Lösung
Ich bin nicht sicher, was Sie mit "funktioneller Weise" bedeuten - meinen Sie, wie in funktionale Programmierung ? Das wird nicht passieren (da Sie intrinsisch sind versucht, ein Objekt zu ändern, die das Gegenteil von FP). Oder meinst du so etwas wie „eine Art und Weise, dass die Arbeiten“?
Für die letztere Interpretation, das große Problem ist der import *
Teil - unter den vielen Problemen, die das nicht verwenden empfehlen, Sie gehen klatschte in eine zu laufen: es führt einen Schnappschuss von was auch immer auf Modulebene Namen werden zu dem Zeitpunkt gebunden (oder nur diejenigen, die in __all__
im Modul enthalten sind, wenn das ist, definiert.) - zukünftige Änderungen an die Bindungen von Namen werden nie in Module reflektiert werden, die zuvor die import *
tat
Warum glauben Sie, Sie müssen die template_module
Namespace in die des Import-Modul verbinden? Wenn Sie nur eine regelmäßige import template_module as tm
tat, dann einfach auf alle relevanten Namen wie tm.this
Bezug genommen wird, wird tm.that
gut funktionieren (einschließlich aller Änderungen Kommissionierung bis zu den Bindungen zu dem Zeitpunkt der Verwendung auf - mit anderen Worten, es verwendet die „late Bindung“-Ansatz, dass Sie hier verlangen erscheinen).
Andere Tipps
Wenn Sie eine Eigenschaft eines Moduls an einer Stelle ändern, wird es auch das gleiche in anderen Orten. Beweis:
Erstellen Sie eine Datei '/tmp/test1.py':
imoprt os
os.path = '' # set os.path (module) to a mere string
os.zzz = 'zzz'
Dann
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'
Jetzt os.path ist eine leere Zeichenfolge auch in der Hauptanwendung und zzz ist überall zu.
Stellt sich heraus, dies hat einen Stoff-zentrierte Lösung.
Sie haben also eine abstrakte some__fab__template.py und ein konkretes fabfile.py , das ‚verlängern‘ die Vorlage einige erforderlichen Variablen beitragen (zum Beispiel Projektname) sollte.
Ich habe es Fabs implementiert Verwendung env Wörterbuch.
In Template-Datei verweisen Sie env.VAR
und im konkreten ' fabfile.py Sie dies tun:
from fabric.api import *
env.VAR = 'some value'
import some__fab__template
def dist():
some__fab__template.dist()