[Edu-sig] looking for explanations... globals dynamic dict

John Zelle john.zelle at wartburg.edu
Mon Mar 28 21:15:14 CEST 2011


Hello,

Isn't the issue here simply that globals does not return a copy of the globals dictionary, it returns THE actual globals dictionary. It's not some sort of callable, it is the globals dictionary, period. There is no such thing as a static dictionary, they are mutable, and this one changes every time you define a new variable. For example, try:

>>> g = globals()
>>> g['k'] = 3
>>> k
3

So when you assign to new variables, this globals dictionary is changing, and that leads to the iteration error. As long as you iterate using existing variables, there is no problem.

>>> g = globals()
>>> k = None
>>> v = None
>>> for k,v in g.items():
...     print k,v
...
g {'g': {...}, '__builtins__': <module '__builtin__' (built-in)>, 'k': 'g', '__package__': None, 'v': {...}, '__name__': '__main__', '__doc__': None}
__builtins__ <module '__builtin__' (built-in)>
k None
__package__ None
v None
__name__ __main__
__doc__ None


--John


________________________________
From: edu-sig-bounces+john.zelle=wartburg.edu at python.org [edu-sig-bounces+john.zelle=wartburg.edu at python.org] on behalf of kirby urner [kirby.urner at gmail.com]
Sent: Monday, March 28, 2011 1:19 PM
To: edu-sig at python.org
Subject: [Edu-sig] looking for explanations... globals dynamic dict


One of my Python students alerted me to this state of affairs.

I understand that what globals( ) returns will fluctuate as new names come and go.

What I less understand is why g isn't just a *snap shot* of what was global at the time globals( ) ran.

Now it's just a dictionary like any other (and yes, it contains itself, as another global).

So when I go to print its items, why should it care that the names k and v have been added.

Why isn't g just a static dictionary?

I guess because it's tied to a callable that gets re-executed whenever g is used.  g.items( ) is like globals( ).items( ) -- another call.


>>> g = globals()
>>> g
{'__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__', '__doc__': None, 'g': {...}, '__package__': None}
>>> len(g)
5
>>> for k, v in g.items():  print(k, v)

__builtins__ <module 'builtins' (built-in)>
Traceback (most recent call last):
  File "<pyshell#156>", line 1, in <module>
    for k, v in g.items():  print(k, v)
RuntimeError: dictionary changed size during iteration
>>> g
{'g': {...}, '__builtins__': <module 'builtins' (built-in)>, 'k': '__builtins__', '__package__': None, 'v': <module 'builtins' (built-in)>, '__name__': '__main__', '__doc__': None}
>>> len(g)
7
>>>


Oh no, not again....

>>> for t,v in g.items():  print(t,v)

g {'g': {...}, '__builtins__': <module 'builtins' (built-in)>, 'k': '__builtins__', '__package__': None, 't': 'g', 'v': {...}, '__name__': '__main__', '__doc__': None}
Traceback (most recent call last):
  File "<pyshell#160>", line 1, in <module>
    for t,v in g.items():  print(t,v)
RuntimeError: dictionary changed size during iteration

This seems to solve the problem:

>>> ================================ RESTART ================================
>>> g = dict(globals())
>>> g
{'__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> for t,v in g.items():  print(t,v)

__builtins__ <module 'builtins' (built-in)>
__name__ __main__
__doc__ None
__package__ None


This behavior still seems a little peculiar.

>>> help(globals)
Help on built-in function globals in module builtins:

globals(...)
    globals() -> dictionary

    Return the dictionary containing the current scope's global variables.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20110328/12b235a1/attachment.html>


More information about the Edu-sig mailing list