On eval and its substitution of globals

P

Paddy

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:
=====

Python 2.4 (#2, Jan 8 2005, 20:18:03)
[GCC 3.3.5 (Debian 1:3.3.5-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 1, in z

ENDTEST
=======

Is there a way to do a deep substitution of the globals?

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.
 
P

Paddy

I have had no reply so on revisiting this I thought I would re-submit
it and point out that there is a question way down at the end :)

Thanks.

===== Original Post =====
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:
=====

Python 2.4 (#2, Jan 8 2005, 20:18:03)
[GCC 3.3.5 (Debian 1:3.3.5-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
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?

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.
 
K

Kent Johnson

Paddy said:
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:
=====



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():
 
P

Paddy

Thanks Kent for your reply.
I had to do as you suggest but I was thinking either it was a kludge,
and there should be a 'deep' substitution of globals, or that there was
a good reason for it to work as it does and some magician would tell
me.
Oh, the third reason could be that it was first implimented that way
and no-one has submitted a patch of course.

Could someone clue me in?

Ta, Paddy.
 
L

Leif K-Brooks

Paddy said:
I had to do as you suggest but I was thinking either it was a kludge,
and there should be a 'deep' substitution of globals, or that there
was a good reason for it to work as it does and some magician would
tell me.

If there was deep substitution of globals, how would functions imported
from different modules behave? Consider this:

--- foo.py ---
from bar import func

data = 24

print func()
print eval('func()', globals(), locals())

--- bar.py ---
data = 42

def func():
return data

--------------------------------------------------------------------

If globals were deeply substituted when using eval, the program would
presumably print "42\n24", which would be far from intuitive. If you
limit the deep substitution to functions in the same module, you're
creating a confusing special case.
 
P

Paddy

Leif wrote:
" If globals were deeply substituted when using eval, the program would
presumably print "42\n24", which would be far from intuitive. If you
limit the deep substitution to functions in the same module, you're
creating a confusing special case. "

I guess I need outside opinions on what should be normal. The
documentation does not mention the case of 'nested' function calls and
so the present action could be documented but there is still the issue
of "should there be a 'deep' globals substitution". I have such a
need, but this is the first time I have had to consider this whole
topic.
I do in fact have the case you mention. I am writing a module that will
manipulate functions of global variables where the functions are
defined in another module.
My module will evaluate those 'other module' functions supplying the
globals itself - which works fine, the problem comes when I create
derivative functions in my module that call the original 'other module'
functions, and then try and evaluate these derivatives supplying the
globals as before. The 'correct' action that I want is for the globals
I supply to eval to be used for all functions called by the code block
as well as for the code block itself.

- Pad.
 
K

Kent Johnson

Paddy said:
I do in fact have the case you mention. I am writing a module that will
manipulate functions of global variables where the functions are
defined in another module.

Would it be possible to have your functions take arguments instead of globals? That would seem to be
a better design.

Kent
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top