2009-09-15 20 views
32

Me gustaría definir globales de una manera "programática". Algo similar a lo que yo quiero hacer sería:¿Cómo programar programáticamente una variable global (módulo)?

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

Específicamente, quiero crear un módulo fundamentalconstants que contiene variables que se puede acceder como fundamentalconstants.electron_mass, etc., donde todos los valores se obtienen a través de análisis de un fichero (de ahí la necesidad de hacer las asignaciones de una manera "programática").

Ahora, la solución anterior exec funcionaría. Pero estoy un poco incómodo con eso, porque me temo que exec no es la forma más limpia de lograr el objetivo de establecer módulos globales.

Respuesta

37

Puede definir variables globales en el diccionario devuelto por variables globales():

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

+1, como 'globals()' puede ser modificado (http://stackoverflow.com/questions/4859217/programmatically-creating-variables-in-python/4859312#4859312). – EOL

+1

Consejo: Definitivamente lea la respuesta de EOL a la que hace referencia arriba. –

+0

Otro buen punto planteado es que los cambios a 'globals()' persistirán sin error, pero no existe tal garantía con 'locals()'. – DuckPuncher

4

Tienes razón, exec es generalmente una mala idea y ciertamente no es necesario en este caso.

La respuesta de Ned está bien. Otra forma posible de hacerlo si eres un módulo es la importación de sí mismo:

fundamentalconstants.py:

import fundamentalconstants 

fundamentalconstants.life_meaning= 42 

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

Prefiero que Nadia "importe [__ nombre__]" a la codificación de este módulo. –

+0

Interesante: ¡No había pensado en eso! Es cierto que no es robusto en contra de cambiar el nombre del archivo del módulo, ¡pero sigue siendo una idea interesante que prefiero mi 'exec'! – EOL

48

Aquí es una mejor manera de hacerlo:

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

¿Quizás podrías describir por qué es mejor? – tom10

+9

@ tom10, no hay garantía documentada de que _changes_ a 'globales()' realmente persistirán los cambios en el módulo subyacente. Funciona hoy, podría romperse mañana. La solución de Nadia OTOH es sólida (por lo tanto, +1 de mí ;-). –

+1

Me gusta esta forma de hacerlo, pero sobre locals() y globales(): los documentos actuales parecen implicar que siempre funcionará: locals: Actualice y devuelva un diccionario que represente la tabla de símbolos locales actual. Advertencia: el contenido de este diccionario no debe modificarse; los cambios pueden no afectar los valores de las variables locales utilizadas por el intérprete. globals: devuelve un diccionario que representa la tabla de símbolos global actual. Este es siempre el diccionario del módulo actual. Tal vez los documentos deben ser ajustados ... –

Cuestiones relacionadas