On eval and its substitution of globals

Kent Johnson kent37 at tds.net
Wed Feb 23 07:29:55 EST 2005


Paddy wrote:
> Hi,
> I got tripped up on the way eval works with respect to modules and
> so wrote a test.
> 
> It seems that a function carries around knowledge of the globals()
> present
> when it was defined. (The .func_globals attribute)?
> 
> When evaluated using eval(...) the embedded globals can be overridden
> with
> the one passed through the eval(...) call
> 
> If however you create a new function that calls the first then eval's
> global argument is only substituted in the outer call!
> 
> TEST:
> =====
> 
>>>>def f1(): return A < B
> 
> ...
> 
>>>>def z(): return f1()
> 
> ...
> 
>>>>eval(f1.func_code,dict(A=1,B=2))
> 
> True
> 
>>>>eval(z.func_code,dict(A=1,B=2, f1=f1))
> 
> 
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 1, in z
>   File "<stdin>", line 1, in f1
> NameError: global name 'A' is not defined
> 
> 
> ENDTEST
> =======
> 
> Is there a way to do a deep substitution of the globals?

A workaround is to implement z() using eval() again, this forces f1() to use the same globals passed 
to z():
  >>> def z(): return eval(f1.func_code)
  ...
  >>> eval(z.func_code,dict(A=1,B=2, f1=f1))
True

Kent

> 
> I should add that f1 is given as-is. I can modify z,
> and f1 is just one of many functions given and function z
> is some boolean function of the f<n>'s
> 
> Thanks, Pad.
> 



More information about the Python-list mailing list