globals() using For Loop against Generator

Mel mwilson at the-wire.com
Tue Mar 18 18:20:56 CET 2008


cokofreedom at gmail.com wrote:
> if __name__ == '__main__':
> 
>     print "Globals (For Loop):"
>     try:
>         for i in globals():
>             print "\t%s" % i
>     except RuntimeError:
>         print "Only some globals() printed\n"
>     else:
>         print "All globals() printed\n"
> 
>     print "Globals (Generator):"
>     try:
>         print "\n".join("\t%s" % i for i in globals())
>     except RuntimeError:
>         print "Only some globals() printed\n"
>     else:
>         print "All globals() printed\n"
> 
>>>> Globals (For Loop):
>>>> 	__builtins__
>>>> Only some globals() printed
>>>>
>>>> Globals (Generator):
>>>> 	__builtins__
>>>> 	__name__
>>>> 	__file__
>>>> 	i
>>>> 	__doc__
>>>> All globals() printed
>>>>
> 
> Why is it with a generator I get everything out but with a for loop I
> don't? I know that globals is not read-only but I would of expected
> the same behaviour from both...

Run the for loop in the interpreter, without catching exceptions.  You get

__builtins__
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration


Then `print globals()` shows that i has been added to the global 
namespace.  If you run the for loop a second time, after i exists, the 
loop runs fine.

Apparently, generator comprehensions have been optimized so that they 
don't expose their working variables.  The generator comprehension 
won't add i to the global namespace, so all is well.

	Mel.



More information about the Python-list mailing list