It's odd to me too at the first glance. But with some more output i found the reason:
>>> g, l = {}, {}
>>> print id(g), id(l)
12311984 12310688
>>>
>>> exec '''
... a = 2
... print 'a' in globals(), 'a' in locals(), id(globals()), id(locals())
... def f():
... print 'a' in globals(), 'a' in locals(), id(globals()), id(locals())
... f()
... ''' in g, l
False True 12311984 12310688
False False 12311984 12311264
As said in http://effbot.org/pyfaq/what-are-the-rules-for-local-and-global-variables-in-python.htm:
In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a new value anywhere within the function’s body, it’s assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as global.
So one solution is use the same dict for globals and locals:
>>> l = {}
>>> exec '''
... a = 2
... def f():
... print a
... f()
... ''' in l, l
2