Why doesn't eval of generator expression work with locals?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Wed Jan 28 20:48:14 CET 2009


En Wed, 28 Jan 2009 16:00:43 -0200, Scott David Daniels  
<Scott.Daniels at acm.org> escribió:
> Gabriel Genellina wrote:
>> En Wed, 28 Jan 2009 01:36:57 -0200, Steve Holden <steve at holdenweb.com>  
>> escribió:
>>> Gabriel Genellina wrote:
>>>> En Tue, 27 Jan 2009 22:17:16 -0200, Robert Kern  
>>>> <robert.kern at gmail.com>
>>>> escribió:
>>
>>>> I *thought* I did understand this until I came to this example:
>>>>
>>>> 1)
>>>>>>> id(globals()), id(locals())
>>>> (11239760, 11239760)
> This is a bad test.  We know distinct objects are distinct, but:
>  >>> print id(object()), id(object())
> 10598120 10598120
>
>  >>> a = object(); b = object()
>  >>> print id(a), id(b)
> 10598120 10598128
>
> The reason is that once your created object has its id taken, you
> must keep a handle on it, otherwise it may get recycled and reused.

It doesn't matter in this case, I think. globals() is always the same  
object and is alive during the whole test. So something having the same  
id() than globals() must be the very same object, and something having a  
different id() than globals() cannot be the same object.

If you like, I can rewrite the example without using id():

>>> L = list(n for n in [globals(),locals()])
>>> L[0] is L[1]
True
>>> L = list(n() for n in [globals,locals])
>>> L[0] is L[1]
False

(I *think* this has to do with free variables in the "right side" (after  
the "in" keyword) of a generator expression; they appear to be evaluated  
when the expression is *defined*, not when is is *used*. By contrast, free  
variables in the "left side" appear to be evaluated when the expression is  
used.)

-- 
Gabriel Genellina




More information about the Python-list mailing list