2010-04-08 8 views
42

Desidero utilizzare un gruppo di variabili locali definite in una funzione, al di fuori della funzione. Quindi sto passando x=locals() nel valore restituito.Python: caricare le variabili in un dominio nello spazio dei nomi

Come posso caricare tutte le variabili definite in quel dizionario nello spazio dei nomi esterno alla funzione, in modo che invece di accedere al valore utilizzando x['variable'], potrei semplicemente utilizzare variable.

+6

Sembra un'idea terribile. –

+4

Meno terribile del concetto di 'from module import *', dal momento che presumibilmente hai una maggiore conoscenza di ciò che è nel ditt. –

+0

@JohnLaRooy perché è una pessima idea? –

risposta

74

consideri il Bunch alternativa:

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

quindi se avete un dizionario d e desidera accedere (lettura) i suoi valori con la sintassi x.foo al posto del goffo d['foo'], basta fare

x = Bunch(d) 

funziona sia all'interno che all'esterno delle funzioni - ed è enormemente più pulito e più sicuro dell'iniezione di d in globals()! Ricordate l'ultima riga dalla Zen di Python ...:

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

Ma sembra così elegante: 'globals(). Update (locals())'! (I kid, I kid) – jathanism

+1

Uso questo aggiornamento globale(). (Locals()) in semplici script di plottaggio in cui ho alcune semplici differenze quando carico il modulo in modo interattivo o eseguo dalla riga di comando in un unico tipo di modo. Suppongo che potrei semplicemente inserire if __name__ == '__main__': all'inizio del file e quindi non avere funzioni ... ma sembra ineleggente. Ad ogni modo, se c'è un modo migliore per passare il valore da una funzione al modulo esterno, sarei interessato. – mathtick

+0

funziona per python 3 o successivo? –

14

Questo è perfettamente valido caso di importare le variabili in uno spazio locale in un altro spazio locale finché uno è consapevole di ciò che lui/lei è facendo. Ho visto un tale codice molte volte usato in modi utili. Basta fare attenzione a non inquinare lo spazio globale comune.

è possibile effettuare le seguenti operazioni:

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

D'accordo, per esempio molti framework di template PHP usano l'esportazione variabile nello spazio dei nomi locale. – Radek

+10

La documentazione di Python afferma che questa è una cattiva idea. Per quanto riguarda i locali(), "I contenuti di questo dizionario non dovrebbero essere modificati, le modifiche potrebbero non influire sui valori delle variabili locali e libere usate dall'interprete." Vedi http://docs.python.org/library/functions.html#locals. –

+3

Vedere anche: https://youtu.be/Ug0iDjbMPVg?t=47m55s – RobinL

7

Importazione di variabili in un namespace locale è un problema valido e spesso utilizzati nei quadri di templating.

di ritorno tutte le variabili locali da una funzione:

return locals() 

Poi importare come segue:

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

Funziona perfettamente ma è molto lento ... non è un problema per i programmi di test semplici però. – snowcrash09

0

C'è sempre questa opzione, non so che è il metodo migliore là fuori, ma sicuramente funziona. Supponendo tipo (x) = dict

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