Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > How do I do this? (eval() on the left hand side)

Reply
Thread Tools

How do I do this? (eval() on the left hand side)

 
 
Steven Bethard
Guest
Posts: n/a
 
      12-09-2004
Jeff Shannon wrote:
> Note also that functions which use exec cannot use the static namespace
> optimization, and thus tend to be *much* slower than normal functions


In what circumstances will this be true? I couldn't verify it:

> cat fib.py

def fib1(n):
a, b = 0, 1
while True:
a, b = b, a + b
yield a


exec """\
def fib2(n):
a, b = 0, 1
while True:
a, b = b, a + b
yield a
"""
> python -m timeit -s "import fib" "fib.fib1(100)"

1000000 loops, best of 3: 0.714 usec per loop

> python -m timeit -s "import fib" "fib.fib2(100)"

1000000 loops, best of 3: 0.705 usec per loop
 
Reply With Quote
 
 
 
 
Jeff Shannon
Guest
Posts: n/a
 
      12-09-2004
Steven Bethard wrote:

> Jeff Shannon wrote:
>
>> Note also that functions which use exec cannot use the static
>> namespace optimization, and thus tend to be *much* slower than normal
>> functions

>
>
> In what circumstances will this be true? I couldn't verify it:
>
> [...]
> exec """\
> def fib2(n):
> a, b = 0, 1
> while True:
> a, b = b, a + b
> yield a
> """



I was referring to functions which have an internal exec statement, not
functions which are created entirely within an exec -- i.e., something
like this:

def fib3(n):
a, b = 0, 1
while True:
exec "a, b = b, a + b"
yield a

In your fib2(), when the function is defined, the entire contents of the
local namespace can be determined (it's just that the function isn't
"defined" until the exec statement is executed). In fib3(), when the
function is defined, the parser can't determine what's happening inside
the exec statement (it just sees a string, and that string may depend on
other runtime circumstances which will happen latter), so it can't say
for certain whether names other than a and b are created. (Consider the
case where the string to be exec'ed is passed in as a function argument...)

Jeff Shannon
Technician/Programmer
Credit International

 
Reply With Quote
 
 
 
 
Terry Reedy
Guest
Posts: n/a
 
      12-09-2004
To respond to and summarize several posts in this discussion:

Within a function, where the local namespace is distinct from the global
(module) namespace, CPython usually implements the local namespace
internally as a fixed-length array. When this is true, locals() is a
*copy* of the local namespace and not the namespace itself. Once that dict
is created, the history of how it was created is immediately forgotten,
just as with any other ordinary Python dict.

That dict can be bound to a name or other target and modified like any
other dict, and there could be reasons to do so. However, modifying it has
no more effect on the local namespace than modifying any other local dict.

Terry J. Reedy



 
Reply With Quote
 
Caleb Hattingh
Guest
Posts: n/a
 
      12-09-2004
Peter, I second that.

Nick

In what way is it unreliable? I can't seem to create a situation where
the update through globals and locals doesn't work. Are you referring
perhaps to the possibility of variables being garbage collected and then
not being around later when one tries to access them through a string
name? I don't know very much about the garbage collector, so I can't say
for sure.

thx
Caleb

On Wed, 08 Dec 2004 10:38:30 -0500, Peter Hansen <> wrote:

> Nick Coghlan wrote:
>> Generally, altering the contents of the dicts returned by locals() and
>> globals() is unreliable at best.

>
> Nick, could you please comment on why you say this about globals()?
> I've never heard of any possibility of "unreliability" in updating
> globals() and, as far as I know, a large body of code exists which
> does in fact rely on this -- much of mine included.
>
> -Peter


 
Reply With Quote
 
Caleb Hattingh
Guest
Posts: n/a
 
      12-09-2004
Steve,

I don't think I understand. Here is what I just tried:

'>>> def f():
x = 3
d = locals()
print x
print d['x']
d['x'] = 5
print x


'>>> f()
3
3
3
'>>>

In your example, x had not yet been initialised, maybe. What I am seeing
is that "x" does not seem to update when being assigned to - I guess this
is what you are referring to by being unreliable.

But "unreliable" sounds kinda vague and intermittent, and I assume that is
not the case here - What is the Rule(tm)?

Thanks
Caleb



On Wed, 08 Dec 2004 16:59:23 GMT, Steven Bethard
<> wrote:

> Peter Hansen wrote:
>> Nick Coghlan wrote:
>>
>>> Generally, altering the contents of the dicts returned by locals() and
>>> globals() is unreliable at best.

>> Nick, could you please comment on why you say this about globals()?
>> I've never heard of any possibility of "unreliability" in updating
>> globals() and, as far as I know, a large body of code exists which
>> does in fact rely on this -- much of mine included.

>
> Updating locals() is unreliable. Updating globals() is fine, AFAIK.
>
> http://docs.python.org/lib/built-in-funcs.html
>
> I believe that the only time that locals() is updatable is when locals()
> is globals():
>
> >>> locals() is globals()

> True
> >>> x

> Traceback (most recent call last):
> File "<interactive input>", line 1, in ?
> NameError: name 'x' is not defined
> >>> locals()['x'] = 3
> >>> x

> 3
>
>
> >>> def f():

> ... print locals() is globals()
> ... locals()['x'] = 3
> ... print x
> ...
> >>> f()

> False
> Traceback (most recent call last):
> File "<interactive input>", line 1, in ?
> File "<interactive input>", line 4, in f
> NameError: global name 'x' is not defined
>
>
> Steve


 
Reply With Quote
 
Caleb Hattingh
Guest
Posts: n/a
 
      12-09-2004
Thx Peter

I verified this situation myself with a post from Steven Bethard earlier
(trying to use "locals" within a function definition).

I am convinced now that locals() doesn't work as (I) expected. Steven
says there was some or other reason why locals() as used in this context
is not writable - Do you know why this is? I really do not like
guidelines like "may not work", "is unreliable" and so on. Perhaps this
is a character flaw, but I really do like to know what works, when it
works, and when it doesn't work.

In this scenario, we can see it doesn't work. To my eyes, it doesn't work
*in the way I expect* (which is highly subjective, no argument there).
Would this be a situation where it would be nice to have an exception
thrown if locals() is assigned to in a scope where it is not writable?

It would also be nice if globals and locals behaved the same, differing
only in scope (which is what I expected originally anyway). But we can't
have everything, I guess

Caleb


On Wed, 08 Dec 2004 20:49:53 +0100, Peter Otten <__peter__@web.de> wrote:

> Caleb Hattingh wrote:
>
>> In what way is it
>> unreliable?ÂÂ*ÂÂ*IÂÂ*can'tÂÂ*seemÂÂ*toÂÂ*createÂÂ*aÂÂ*situationÂÂ*where
>> the update through globals and locals doesn't
>> work.ÂÂ*ÂÂ*ÂÂ*AreÂÂ*youÂÂ*referring

>
> Updates to a locals() dictionary may not be reflected by the variables in
> the local scope, e. g.:
>
>>>> def f():

> ... locals()["a"] = 1
> ... print a
> ...
>>>> f()

> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<stdin>", line 3, in f
> NameError: global name 'a' is not defined
>>>> def f():

> ... a = 42
> ... locals()["a"] = 1
> ... print a
> ...
>>>> f()

> 42
>
> Updating globals() should be safe.
> Peter
>


 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      12-09-2004
Jeff Shannon wrote:
> Steven Bethard wrote:
>
>> Jeff Shannon wrote:
>>
>>> Note also that functions which use exec cannot use the static
>>> namespace optimization, and thus tend to be *much* slower than normal
>>> functions

>>
>> In what circumstances will this be true? I couldn't verify it:

[snip]
>
> I was referring to functions which have an internal exec statement, not
> functions which are created entirely within an exec -- i.e., something
> like this:


Thanks for the clarification. Here's the results for some functions
with internal exec statements:

> cat fib.py

def fib1(n):
a, b = 0, 1
while True:
a, b = b, a + b
yield a


exec """\
def fib2(n):
a, b = 0, 1
while True:
a, b = b, a + b
yield a
"""

def fib3(n):
a, b = 0, 1
while True:
exec "a, b = b, a + b"
yield a

def fib4(n):
exec "a, b = 0, 1"
while True:
exec "a, b = b, a + b"
yield a

>
> python -m timeit -s "import fib" "fib.fib1(100)"

1000000 loops, best of 3: 0.71 usec per loop

> python -m timeit -s "import fib" "fib.fib2(100)"

1000000 loops, best of 3: 0.678 usec per loop

> python -m timeit -s "import fib" "fib.fib3(100)"

1000000 loops, best of 3: 0.826 usec per loop

> python -m timeit -s "import fib" "fib.fib4(100)"

1000000 loops, best of 3: 0.821 usec per loop

I'm not sure I'd say they're *much* slower, but you're right; they're
definitely slower.

Steve
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      12-09-2004
Peter Hansen wrote:

> Caleb Hattingh wrote:
>> I am convinced now that locals() doesn't work as (I) expected. Steven
>> says there was some or other reason why locals() as used in this
>> context is not writable - Do you know why this is? I really do not
>> like guidelines like "may not work", "is unreliable" and so on.
>> Perhaps this is a character flaw, but I really do like to know what
>> works, when it works, and when it doesn't work.

>
> Those who've talked about it being "unreliable" are misstating
> the Rule that you are looking for. I'll quote it below, so
> that you aren't left in this unfortunate state of limbo:
>
> The Rule of locals()
> Updating locals() should not be done. Treat the
> return value of locals() as read-only. Never try
> to update it. End of story.
>
> Anything that appears to suggest that locals() might sometimes
> actually be writable is not really happening. Look the other
> way. Pay no attention to the man behind the curtain. And
> especially, whatever else you do, don't let the PSU se


I agree. But much of the confusion stems from interpreter experiments like

>>> locals()["a"] = 42
>>> a

42

That would go away if locals() returned an ignore-write proxy where the
global and local scope are identical. The ability to "just try it" is an
asset.

Peter



 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      12-09-2004
Caleb Hattingh wrote:

> I am convinced now that locals() doesn't work as (I) expected. Steven
> says there was some or other reason why locals() as used in this context
> is not writable - Do you know why this is? I really do not like
> guidelines like "may not work", "is unreliable" and so on. Perhaps this
> is a character flaw, but I really do like to know what works, when it
> works, and when it doesn't work.


I think Peter Hansen has answered that. Your expectations were just wrong.

> In this scenario, we can see it doesn't work. To my eyes, it doesn't work
> *in the way I expect* (which is highly subjective, no argument there).
> Would this be a situation where it would be nice to have an exception
> thrown if locals() is assigned to in a scope where it is not writable?


If python were to throw an exception, it should always be thrown. But I'm
the wrong one to worry about that as I didn't even find a single

globals()[name] = value

assignment in my scripts. I want to know a variable's name, or I put it in a
dictionary.

> It would also be nice if globals and locals behaved the same, differing
> only in scope (which is what I expected originally anyway). But we can't
> have everything, I guess


That would mean that both would become read-only, I guess, but I don't see
that happen.

Peter

 
Reply With Quote
 
Nick Coghlan
Guest
Posts: n/a
 
      12-09-2004
Peter Hansen wrote:
> Nick Coghlan wrote:
>
>> Generally, altering the contents of the dicts returned by locals() and
>> globals() is unreliable at best.

>
>
> Nick, could you please comment on why you say this about globals()?
> I've never heard of any possibility of "unreliability" in updating
> globals() and, as far as I know, a large body of code exists which
> does in fact rely on this -- much of mine included.


As Steve pointed out, I was, well, flat out wrong. You're quite correct - it's
only locals() that can cause a problem.

Cheers,
Nick.

--
Nick Coghlan | | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Microsoft Left Hand, Meet Microsoft Right Hand Lawrence D'Oliveiro NZ Computing 1 03-07-2011 03:55 AM
Seek cooperation Expect hand in hand xianzeguanggao Digital Photography 0 06-14-2007 08:07 AM
Left panel on left hand side of desktop on windows xp wish to get rid of Bun Mui Computer Support 1 09-14-2004 03:40 AM
Left-hand menu in CSS Kim André Akerø HTML 7 06-07-2004 06:58 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57