[Disclaimer: ci possono essere modi più divinatorio di fare quello che voglio fare, ma voglio sapere come scoping del pitone lavora qui]Come iniettare variabile in ambito con un decoratore in python
sto cercando trovare un modo per fare un decoratore che faccia qualcosa come iniettare un nome nell'ambito di un'altra funzione (in modo che il nome non perda fuori dall'ambito del decoratore). Ad esempio, se ho una funzione che dice di stampare una variabile denominata var
che non è stata definita, vorrei definirla all'interno di un decoratore dove viene chiamata. Ecco un esempio che rompe:
c = 'Message'
def decorator_factory(value):
def msg_decorator(f):
def inner_dec(*args, **kwargs):
var = value
res = f(*args, **kwargs)
return res
return inner_dec
return msg_decorator
@decorator_factory(c)
def msg_printer():
print var
msg_printer()
Vorrei per stampare 'Messaggio', ma dà:
NameError: global name 'var' is not defined
traceback anche punti per wher var
è definito:
<ipython-input-25-34b84bee70dc> in inner_dec(*args, **kwargs)
8 def inner_dec(*args, **kwargs):
9 var = value
---> 10 res = f(*args, **kwargs)
11 return res
12 return inner_dec
quindi non capisco perché non riesca a trovare var
.
C'è un modo per fare qualcosa di simile?
Quindi, se faccio 'def msg_printer(): var' stampa e provare a chiamare' msg_printer', ottengo lo stesso errore di nome, ma se poi mi definisco ' var = 'Ciao' e chiamalo, lo stampa bene. In questo esempio, 'var' non viene definito in fase di esecuzione, dopo che' msg_printer' è stato compilato? – beardc
Poiché 'var' non è definito nella funzione o negli ambiti parent,' var' è segnato, al momento della compilazione, come nome globale. Ma se ci fosse un ambito genitore, allora al momento della compilazione, 'var' verrebbe invece contrassegnato come un nome con scope, a quel punto il trucco decorator non funzionerebbe più neanche. –
Non capisco. 'func_globals' dovrebbe essere di sola lettura, secondo la bella tabella del modello di dati: http://docs.python.org/2/reference/datamodel.html – n611x007