Può essere utile in 'dichiarative python'.Ad esempio, nel testo sotto FooDef
e BarDef
sono le classi utilizzate per definire una serie di strutture di dati che vengono poi utilizzate da qualche pacchetto come input o dalla sua configurazione. Ciò ti consente molta flessibilità in ciò che è il tuo input, e non hai bisogno di scrivere un parser.
# 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')
Si noti che questo file di configurazione utilizza un ciclo per costruire una lista di nomi che fanno parte della configurazione di Foo_other
. Quindi, questo linguaggio di configurazione ha un preprocessore molto potente, con una libreria run-time disponibile. Nel caso in cui si desideri, ad esempio, trovare un registro complesso o estrarre elementi da un file zip e decodificarli in base64, come parte della generazione della configurazione (questo approccio non è raccomandato, ovviamente, per i casi in cui l'input può provenire da fonte non attendibile ...)
il pacchetto di legge la configurazione utilizzando qualcosa di simile al seguente:
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
Così, finalmente arrivando al punto, globals()
è utile, quando si utilizza un tale pacchetto, se si desidera coniare una serie di definizioni proceduralmente:
for idx in range(20):
varname = "Foo_%02d" % i
globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i)
Ciò equivale alla scrittura
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 esempio di un pacchetto che ottiene il suo ingresso raccogliendo un gruppo di definizioni di un modulo pitone è CAPI (Python-lex-yacc) http://www.dabeaz.com/ply/ - in quel caso la gli oggetti sono per lo più oggetti funzione, ma anche i metadati dagli oggetti funzione (i loro nomi, docstring e ordine di definizione) fanno parte dell'input. Non è un buon esempio per l'uso di globals()
. Inoltre, viene importato dalla 'configurazione' - quest'ultima è un normale script python - piuttosto che viceversa.
Ho usato 'declarative python' su alcuni progetti su cui ho lavorato e ho avuto occasione di usare globals()
durante la scrittura di configurazioni per questi. Si potrebbe certamente sostenere che ciò è dovuto a un punto debole nel modo in cui è stato progettato il "linguaggio" di configurazione. L'uso di globals()
in questo modo non produce risultati molto chiari; solo risultati che potrebbero essere più facili da mantenere rispetto alla scrittura di una dozzina di dichiarazioni quasi identiche.
Si può anche usare per dare variabili importanza all'interno del file di configurazione, secondo i loro nomi:
# 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")
Questo metodo potrebbe essere utile per qualsiasi modulo python che definisce un sacco di tavoli e delle strutture, per semplificare l'aggiunta di elementi ai dati, senza dover mantenere anche i riferimenti.
"Ma non si dovrebbe mai incontrare il problema di avere due variabili con lo stesso nome e di usarle entrambe nello stesso ambito." Non posso seguire questo pensiero. Questa è l'intera ragione per spazi dei nomi separati, che hai variabili con lo stesso nome in ambiti diversi. Quando lavori con due di essi, i nomi duplicati sono una cosa naturale, ma non un problema, dato che puoi prefissarli. – Michael
Bene, vengo dalla famiglia C++, quindi non sono sicuro delle persone Python, ma per quanto posso pensare, non dovresti avere una variabile ** globale ** che non ha un nome univoco. Certo ci saranno variabili con lo stesso nome, nello stesso ambito, che è stata una mia stupida frase, ma non globali con lo stesso nome di quelli locali. Ecco quando userei spazi dei nomi per quelli locali ... Ma non so, se lo dici tu. –
@Mahi: 'globals' è forse un po 'fuorviante. 'globals()' è essenzialmente il 'locals()' di un modulo.Il Python più vicino arriva a globals che sono veramente globali per tutto il tuo programma è il modulo ['__builtin__'] (http://docs.python.org/library/__builtin__.html); tutto ciò che aggiungi al modulo * that * diventa disponibile in tutti i namespace ovunque. –