Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange global variable behavior on import [duplicate]

Yes: I know that we shouldn't be using global variables in Python but I'm trying to understand this behavior.

I have this file called bug.py :

x = 0


def foo():
    global x
    x = 100


if __name__ == '__main__':
    foo()
    print(x)

when I execute this as a file I get the expected result of a 100, see below.

(mani) franz@ubuntu:~/dropboxpython/poolparty$ python bug.py
100

However, when I do the same thing in the repl, x doesn't turn 100, see below

(mani) franz@ubuntu:~/dropboxpython/poolparty$ python
Python 3.6.4 | packaged by conda-forge | (default, Dec 23 2017, 16:31:06) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bug import *
>>> x
0
>>> foo()
>>> x
0

Why does this happen?

like image 996
Jans Aasman Avatar asked Jan 02 '26 00:01

Jans Aasman


1 Answers

Let's recap what is the from module import something statement doing:

a reference to that value is stored in the local namespace, using the name in the as clause if it is present, otherwise using the attribute name

I'd like to add also that module is imported (i.e. added to sys.modules), but the name module is not created.

The second important point is that integers are immutable. Immutable objects behave like this, because each value is a separate object:

a = 0 # a-->0
b = a # a-->0<--b
a = 3 # 3<--a 0<--b; new object int(3) is created; b is still 0

So what is happeing is the import creates a local x initialized to x from bug which is zero. Calling foo() changes x in the bug module, but as shown above, it cannot affect the local x.


Try this to see the difference between immutable x and mutable y:

x = 0
y = [0]

def foo():
    global x, y
    x = 100
    y[0] = 100

if __name__ == '__main__':
    foo()
    print(x)
    print(y)
>>> from bug import *
>>> x, y
(0, [0])
>>> foo()
>>> x, y
(0, [100])
>>> 

UPDATE: checking the x set by foo.

>>> import sys
>>> sys.modules['bug'].x
100
like image 94
VPfB Avatar answered Jan 03 '26 17:01

VPfB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!