Reputation: 15641
File a.py:
def f():
pass
File main.py:
import a
print("f globals")
print(a.f.__globals__)
def g():
pass
print("g globals")
print(g.__globals__)
a.f.__globals__
have much more elements than g.__globals__
. At the first look it seems that built-in functions and types are in a.f.__globals__
. Why these two dictionaries are different?
Upvotes: 3
Views: 6939
Reputation: 1124548
You are looking at the module namespaces. The f()
globals differs from g()
globals because they both live in different modules.
You'll see the same global namespace if you use vars()
(for globals in main
) and vars(a)
(for the globals of module a
):
print(sorted(vars(a).keys() - vars()))
# prints ['__initializing__', 'f'], only `a` has `f` defined, the `__initializing__` value is a flag used by the import machinery
print(sorted(vars().keys() - vars(a)))
# prints ['a', 'g'], only `main` has imported `a` and defined function `g`
Each and every module gets its own namespace, globals()
are not interpreter global, they are module global only. Importing a module means you are importing a reference to that namespace, or creating references to names in that namespace.
From the datamodel documentation on module objects:
A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the
__globals__
attribute of functions defined in the module)
and on function objects:
__globals__
: A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined.
The __builtins__
key of the main script merely points to the __builtins__
module, in imported modules that has been expanded into a dictionary. These are the same thing, really.
Upvotes: 4