Puede ser útil en 'declarative python'.Por ejemplo, en el siguiente FooDef
y BarDef
son clases usadas para definir una serie de estructuras de datos que luego son utilizadas por algún paquete como su entrada o su configuración. Esto le permite mucha flexibilidad en lo que se refiere a su entrada, y no necesita escribir un analizador.
# FooDef, BarDef are classes
Foo_one = FooDef("This one", opt1 = False, valence = 3)
Foo_two = FooDef("The other one", valence = 6, parent = Foo_one)
namelist = []
for i in range(6):
namelist.append("nm%03d"%i)
Foo_other = FooDef("a third one", string_list = namelist)
Bar_thing = BarDef((Foo_one, Foo_two), method = 'depth-first')
Tenga en cuenta que este archivo de configuración utiliza un bucle para construir una lista de nombres que son parte de la configuración de Foo_other
. Entonces, este lenguaje de configuración viene con un 'preprocesador' muy poderoso, con una biblioteca de tiempo de ejecución disponible. En caso de que quiera, digamos, encontrar un registro complejo, o extraer elementos de un archivo zip y decodificarlos en base64, como parte de la generación de su configuración (este enfoque no es recomendable, por supuesto, para los casos en que la entrada puede ser de un fuente no confiable ...)
el paquete lee la configuración de usar algo como lo siguiente:
conf_globals = {} # make a namespace
# Give the config file the classes it needs
conf_globals['FooDef']= mypkgconfig.FooDef # both of these are based ...
conf_globals['BarDef']= mypkgconfig.BarDef # ... on .DefBase
fname = "user.conf"
try:
exec open(fname) in conf_globals
except Exception:
...as needed...
# now find all the definitions in there
# (I'm assuming the names they are defined with are
# significant to interpreting the data; so they
# are stored under those keys here).
defs = {}
for nm,val in conf_globals.items():
if isinstance(val,mypkgconfig.DefBase):
defs[nm] = val
Así que, finalmente llegando al punto, globals()
es útil, cuando se utiliza un envase de este tipo, si se quiere acuñar una serie de definiciones procesales:
for idx in range(20):
varname = "Foo_%02d" % i
globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i)
Esto es equivalente a escribir
Foo_00 = FooDef("one of several", id_code = 1, scale_ratio=1)
Foo_01 = FooDef("one of several", id_code = 2, scale_ratio=2)
Foo_02 = FooDef("one of several", id_code = 3, scale_ratio=4)
... 17 more ...
Un ejemplo de un paquete que obtiene su entrada mediante la recopilación de un montón de definiciones de un módulo de Python es PLY (Python-lex-yacc) http://www.dabeaz.com/ply/ - en ese caso el los objetos son en su mayoría objetos de función, pero los metadatos de los objetos de función (sus nombres, cadenas de documentos y orden de definición) también forman parte de la entrada. No es un buen ejemplo para el uso de globals()
. Además, es importado por la 'configuración', siendo esta última una secuencia de comandos python normal, y no al revés.
He usado 'declarative python' en algunos proyectos en los que he trabajado, y he tenido ocasión de usar globals()
al escribir configuraciones para ellos. Ciertamente se podría argumentar que esto se debió a una debilidad en la forma en que se diseñó el 'lenguaje' de configuración. El uso de globals()
de esta manera no produce resultados muy claros; solo resultados que podrían ser más fáciles de mantener que escribir una docena de declaraciones casi idénticas.
También puede usarlo para dar variables de importancia dentro del archivo de configuración, según sus nombres:
# All variables above here starting with Foo_k_ are collected
# in Bar_klist
#
foo_k = [ v for k,v in globals().items() if k.startswith('Foo_k_')]
Bar_klist = BarDef(foo_k , method = "kset")
Este método podría ser útil para cualquier módulo pitón que define un montón de mesas y estructuras, para que sea más fácil agregar elementos a los datos, sin tener que mantener las referencias también.
"Pero nunca se debe tener el problema de tener dos variables con el mismo nombre y la necesidad de usarlas dentro del mismo ámbito". No puedo seguir este pensamiento. Esa es toda la razón para espacios de nombres separados, que tiene variables con el mismo nombre en diferentes ámbitos. Cuando trabaja con dos de ellos, los nombres duplicados son algo natural, pero no un problema, ya que puede prefijarlos. – Michael
Bueno, vengo de la familia C++, así que no estoy seguro acerca de la gente de Python, pero por lo que puedo pensar, no debería tener una variable ** global ** que no tenga un nombre único. Seguro que habrá variables con el mismo nombre, en el mismo ámbito, esa fue una frase estúpida de mí, pero no globales con los mismos nombres que los locales. Ahí es cuando usaría espacios de nombres para los locales ... Pero no sé, si tú lo dices. –
@Mahi: 'globals' es quizás un poco engañoso. 'globals()' es esencialmente el 'locals()' de un módulo.El Python más cercano a los globales que son verdaderamente globales para todo su programa es el módulo ['__builtin__'] (http://docs.python.org/library/__builtin__.html); cualquier cosa que agregue a * ese * módulo estará disponible en todos los espacios de nombres en todas partes. –