In the file foo.py
I have this:
d = {}
d['x'] = 0
x = 0
def foo():
global d
global x
d['x'] = 1
x = 1
Then in an interpreter:
>>> from foo import *
>>> d['x']
0
>>> x
0
>>> foo()
>>> d['x']
1
>>> x
0
I expected this:
>>> x
1
What am I not understanding?
The global namespace of foo
is imported into your current namespace only once (when you do the from foo import *
). After that, if you change foo
's namespace, it won't be reflected in your current namespace.
Note that you can still change objects in foo
's namespace and see the changed in your current namespace. That is why you see changes in d
. You still have a reference to the same object d
that lives in foo
's namespace.
But, when you set:
x = 1
This rebinds a new object in the namespace of foo
.
Your foo
module and the main module that imports it (named __main__
) have separate namespaces.
Here's what happens:
foo
sets foo
's global variable x
to refer to the integer object 0
.__main__
as the global variable x
.foo.foo()
, which sets foo
's global variable x
to refer to the integer object 1
.__main__
's global variable x
. Because you never changed what this x
refers to, it still refers to 0
, which is what is printed.In short, importing a name into a module does not create any kind of binding between the names in the two modules. They initially refer to the same value, but if one name is re-bound to a different object, the other does not necessarily follow.
This is (one) reason why import foo
is generally a better idea. Referring to foo.x
explicitly in __main__
refers exactly to foo
's global variable x
, and will refer to the name's current value even if it has been changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With