2009-09-15 18 views
32

Ich möchte Globals auf eine "programmatische" Weise definieren. Etwas Ähnliches, was ich will zu tun wäre:Wie programmgesteuert eine globale (Modul) Variable festlegen?

definitions = {'a': 1, 'b': 2, 'c': 123.4} 
for definition in definitions.items(): 
    exec("%s = %r" % definition) # a = 1, etc. 

Insbesondere möchte ich fundamentalconstants ein Modul erstellen, die Variablen enthält, die als fundamentalconstants.electron_mass zugegriffen werden kann usw., wobei alle Werte erhalten werden durch eine Datei Parsen (daher die Notwendigkeit, die Aufgaben "programmatisch" zu erledigen.

Jetzt würde die obige exec Lösung funktionieren. Aber ich bin ein bisschen unruhig, weil ich befürchte, dass exec nicht der sauberste Weg ist, um das Ziel zu erreichen, Modul Globals zu setzen.

Antwort

37

Sie können Globals() zurückgegeben Globals im Wörterbuch festgelegt:

definitions = {'a': 1, 'b': 2, 'c': 123.4} 
for name, value in definitions.items(): 
    globals()[name] = value 
+9

+1, wie 'globals()' kann in der Tat geändert werden (http://stackoverflow.com/questions/4859217/programma/creating-variables-in-python/4859312#4859312). – EOL

+1

Tipp: Lesen Sie auf jeden Fall die Antwort von EOL, auf die er oben Bezug nimmt. –

+0

Ein weiterer guter Punkt ist, dass Änderungen an 'globals()' ohne Fehler fortbestehen, aber es gibt keine solche Garantie mit 'locals()'. – DuckPuncher

4

Du hast Recht, exec ist in der Regel eine schlechte Idee, und es wird sicherlich in diesem Fall nicht erforderlich.

Neds Antwort ist in Ordnung. Eine andere Möglichkeit, es zu tun, wenn Sie ein Modul sind, ist selbst zu importieren:

fundamentalconstants.py:

import fundamentalconstants 

fundamentalconstants.life_meaning= 42 

for line in open('constants.dat'): 
    name, _, value= line.partition(':') 
    setattr(fundamentalconstants, name, value) 
+4

Ich bevorzuge Nadias 'import [__ name __]', um den Namen dieses Moduls hart zu codieren. –

+0

Interessant: Daran hatte ich nicht gedacht! Es ist wahr, dass es nicht robust gegen das Ändern des Moduldateinamens ist, aber es ist immer noch eine interessante Idee, die ich meinem 'exec' vorziehe! – EOL

48

Hier ist ein besserer Weg, es zu tun:

import sys 
definitions = {'a': 1, 'b': 2, 'c': 123.4} 
module = sys.modules[__name__] 
for name, value in definitions.iteritems(): 
    setattr(module, name, value) 
+6

Vielleicht könnten Sie beschreiben, warum das besser ist? – tom10

+9

@ tom10, es gibt keine dokumentierte Garantie, dass _changes_ to 'globals()' die Änderungen am zugrunde liegenden Modul tatsächlich beibehalten wird. Es funktioniert heute, könnte morgen brechen. Nadias Lösung OTOH ist solide (daher +1 von mir ;-). –

+1

Ich mag diese Art, es zu tun, aber über local() und globals(): die aktuellen Dokumente scheinen zu implizieren, dass es immer funktioniert: Locals: Aktualisieren und ein Wörterbuch der aktuellen lokalen Symboltabelle zurückgeben. Warnung: Der Inhalt dieses Wörterbuchs sollte nicht geändert werden. Änderungen können sich nicht auf die Werte der lokalen Variablen auswirken, die vom Interpreter verwendet werden. globals: Gibt ein Wörterbuch zurück, das die aktuelle globale Symboltabelle darstellt. Dies ist immer das Wörterbuch des aktuellen Moduls. Vielleicht müssen die Dokumente verbessert werden ... –

Verwandte Themen