2010-04-08 11 views
42

Ich möchte eine Reihe von lokalen Variablen verwenden, die in einer Funktion außerhalb der Funktion definiert sind. So übergebe ich x=locals() im Rückgabewert.Python: Laden von Variablen in einem Dict in Namespace

Wie kann ich alle in diesem Wörterbuch definierten Variablen in den Namespace außerhalb der Funktion laden, so dass ich statt x['variable'] einfach den Wert variable verwenden kann.

+6

Das klingt nach einer schrecklichen Idee. –

+4

Weniger schrecklich als das Konzept von 'aus Modulimport *', da Sie vermutlich mehr wissen, was im Diktat steht. –

+0

@JohnLaRooy Warum ist das eine schreckliche Idee? –

Antwort

74

Betrachten Sie die Bunch Alternative:

class Bunch(object): 
    def __init__(self, adict): 
    self.__dict__.update(adict) 

so, wenn Sie ein Wörterbuch d und möchten Zugriff (Lesen) ihre Werte mit der Syntax x.foo anstelle des clumsier d['foo'] haben, nur tun

x = Bunch(d) 

Dies funktioniert sowohl innerhalb als auch außerhalb von Funktionen - und es ist enorm sauberer und sicherer als das Einspritzen d in globals()! Denken Sie daran, die letzte Zeile aus der Zen of Python ...:

>>> import this 
The Zen of Python, by Tim Peters 
    ... 
Namespaces are one honking great idea -- let's do more of those! 
+9

Aber das sieht so elegant aus: 'globals(). Update (localhosts())! (Ich scherze, ich kid) – jathanism

+1

Ich benutze diese globals(). Update (localhosts()) in einfachen Plot-Skripten, wo ich einen einfachen Unterschied habe, wenn ich das Modul interaktiv laden oder von der Befehlszeile in einer Art von Weg. Ich nehme an, ich könnte einfach das If __name__ == '__main__': am Anfang der Datei und dann keine Funktionen ... aber das scheint genauso unelegant. Wie auch immer, wenn es einen besseren Weg gibt, den Wert von innerhalb einer Funktion an das äußere Modul zu übergeben, wäre ich interessiert. – mathtick

+0

funktioniert das für Python 3 oder höher? –

14

Dies ist absolut gültige Fall importieren Variablen in einem lokalen Raum in einer anderen lokalen Raum solange man sich bewusst ist, was er/sie tun. Ich habe gesehen, dass solcher Code viele Male auf nützliche Weise verwendet wurde. Man muss nur aufpassen, den globalen Raum nicht zu verschmutzen.

Sie können folgendes tun:

adict = { 'x' : 'I am x', 'y' : ' I am y' } 
locals().update(adict) 
blah(x) 
blah(y) 
+0

Einverstanden, zum Beispiel verwenden viele PHP-Template-Frameworks den variablen Export in den lokalen Namespace. – Radek

+10

Python-Dokumentation besagt, dass dies eine schlechte Idee ist. In Bezug auf local(), "Der Inhalt dieses Wörterbuchs sollte nicht geändert werden; Änderungen können sich nicht auf die Werte der vom Interpreter verwendeten lokalen und freien Variablen auswirken." Siehe http://docs.python.org/library/functions.html#locals. –

+3

Siehe auch: https://youtu.be/Ug0iDjbMPVg?t=47m55s – RobinL

7

Variablen in einen lokalen Namensraum zu importieren ist ein gültiges Problem und oft in Templating-Frameworks genutzt.

Zurück alle lokalen Variablen aus einer Funktion:

return locals() 

Dann importieren wie folgt:

r = fce() 
for key in r.keys(): 
    exec(key + " = r['" + key + "']") 
+2

Funktioniert perfekt, ist aber sehr langsam ... kein Problem für einfache Testprogramme. – snowcrash09

0

Es gibt immer diese Option, ich weiß nicht, dass es die beste Methode ist, gibt, aber es funktioniert wirklich. Angenommen Typ (x) = dict

for key, val in x.items(): # unpack the keys from the dictionary to individual variables 
    exec (key + '=val')