2013-11-22 9 views
6

Sono un po 'curioso perché il codice seguente solleva uno NameError.exec non rileva le variabili dalla chiusura

>>> s = """ 
... foo = [1,2,3] 
... def bar(): 
... return foo[1] 
... """ 
>>> namespace = {} 
>>> exec(s, {'__builtins__': None}, namespace) 
>>> print namespace 
{'foo': [1, 2, 3], 'bar': <function bar at 0x7f79871bd0c8>} 
>>> namespace['bar']() 

al normale livello di interprete, possiamo trovare foo in bar.func_globals o bar.func_closure se in una funzione. Credo che sto chiedendo perché namespace['bar'] non mette in foofunc_closure ...

risposta

4

Si scopre che la risposta era lì tutti insieme nella docs:

Se due oggetti separati sono dati come globali e i locali, il codice verrà eseguito come se fosse incorporato in una definizione di classe.

Dal momento che sto passando sia globals e locals, viene eseguito come se fosse in una classe.

class Foo(object): 
    foo = [1,2,3] 
    @staticmethod 
    def bar(): 
     return foo[1] 

non sorprendentemente non funziona :).

Per chiunque sia interessato a una soluzione, è possibile iniettare namespace nuovamente dentro namespace['bar'].func_globals (inspired by this):

>>> namespace['bar'].func_globals.update(namespace) 
>>> namespace['bar']() 
2 

Nizza.

Sarebbe namespace['bar'].__globals__.update su python3.x