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....@python.org [edu-sig-bounces+john.zelle=wartburg....@python.org] on behalf of kirby urner [kirby.ur...@gmail.com] Sent: Monday, March 28, 2011 1:19 PM To: edu-sig@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.
_______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig