After several years of regular Python use, I really admire that things work how I expect about 90% of the time. To be fair, the other 10% is typically user error. It is easy to overlook nuances in a language, even if you should know better.
I ran into this gotcha in Python recently: when importing a global variable from a module explicitly by name, that variable will be bound to the local namespace. If that bound global is of immutable type (such as the built-in integer type), changes to that variable will not be reflected in the original namespace. Whew, that was an exhausting explanation, an example demonstrates the issue nicely.
Consider the following three Python files,
foo = 10 def func(): print "info5:", foo
Our example module (
mymod.py) defines a global variable and function that uses that global.
from mymod import foo, func _ = None; print "info1:", [_ for _ in globals() if not _.startswith("_")] print "info2:", foo, id(foo) func() foo += 1 print "info3:", foo, id(foo) func()
Our first example of using
mymod imports the global and function by name. The global is updated by
main1.py and then the function is called. However, because the imported
foo was updated, it no longer points to the same object as
foo in the
mymod namespace. The output of this script is the following:
info1: ['func', 'foo'] info2: 10 11159084 info5: 10 11159084 info3: 11 11159072 info5: 10 11159084
import mymod _ = None; print "info1:", [_ for _ in globals() if not _.startswith("_")] print "info2:", mymod.foo, id(mymod.foo) mymod.func() mymod.foo += 1 print "info3:", mymod.foo, id(mymod.foo) mymod.func()
Our second example of using
mymod imports only the module. Since the
foo global is updated and accessed via the
mymod namespace, the changes will be reflected both in
mymod. The output of this script is the following:
info1: ['mymod'] info2: 10 32982572 info5: 10 32982572 info3: 11 32982560 info5: 11 32982560
Please note that this gotcha only applies if the global variable is of immutable type. If the variable is mutable, such as a list or dictionary, this particular issue would not be expressed.