2010-04-08 19 views
42

Quiero usar un conjunto de variables locales definidas en una función, fuera de la función. Así que estoy pasando x=locals() en el valor de retorno.Python: cargar variables en un dict en el espacio de nombres

¿Cómo puedo cargar todas las variables definidas en ese diccionario en el espacio de nombres fuera de la función, de modo que en lugar de acceder al valor usando x['variable'], podría simplemente usar variable.

+6

Eso suena como una idea terrible. –

+4

Menos terrible que el concepto de 'de importación de módulo *', ya que presumiblemente usted tiene más conocimiento de lo que contiene el dict. –

+0

@JohnLaRooy ¿por qué es esta una idea terrible? –

Respuesta

74

Considere la Bunch alternativa:

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

por lo que si usted tiene un diccionario d y desea acceder (leer) sus valores con la sintaxis x.foo en lugar de la más torpe d['foo'], acaba de hacer

x = Bunch(d) 

esto funciona tanto dentro como fuera de funciones - y es enormemente más limpio y más seguro que inyectar d en globals()! Recuerde la última línea del Zen de Python ...:

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

Pero esto se ve tan elegante: 'globals(). Update (locals())'! (Yo chico, engaño) – jathanism

+1

Utilizo este globals(). Update (locals()) en scripts de trazado simple donde tengo una diferencia simple cuando cargo el módulo de forma interactiva o ejecuto desde la línea de comando en un tipo único de camino. Supongo que podría poner el if __name__ == '__main__': en la parte superior del archivo y luego no tener funciones ... pero eso parece tan poco elegante. De todos modos, si hay una forma mejor de pasar el valor desde el interior de una función al módulo externo, estaría interesado. – mathtick

+0

¿funciona esto para python 3 o superior? –

14

Este es el caso perfectamente válida para importar las variables en un espacio local en otro espacio local, siempre y cuando uno es consciente de lo que él/ella está obra. He visto este código muchas veces siendo utilizado de manera útil. Solo hay que tener cuidado de no contaminar el espacio global común.

Usted puede hacer lo siguiente:

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

De acuerdo, por ejemplo, muchos frameworks de plantillas PHP usan la exportación de variables en el espacio de nombres local. – Radek

+10

La documentación de Python indica que esta es una mala idea. Con respecto a los lugareños(), "El contenido de este diccionario no debe modificarse, los cambios pueden no afectar los valores de las variables locales y gratuitas utilizadas por el intérprete". Ver http://docs.python.org/library/functions.html#locals. –

+3

Vea también: https://youtu.be/Ug0iDjbMPVg?t=47m55s – RobinL

7

Importación de variables en un espacio de nombres local es un problema válida y, a menudo utilizados en los marcos de plantillas.

Retorno todas las variables locales de una función:

return locals() 

A continuación, importar la forma siguiente:

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

Funciona perfectamente pero es muy lento ... aunque no es un problema para los programas de prueba simples. – snowcrash09

0

Hay siempre esta opción, no sé que es el mejor método por ahí, pero seguro que funciona Asumiendo type (x) = dict

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