Python Forum

Full Version: Global variables not changing
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I've had a problem with some code where a global variable reverted back to its previous value, after a function completed, despite the variable being named global in that same function. To illustrate, I made a little example, that demonstrates the problem.

I would expect the second print statement to print 5, but instead it prints None. Can this be fixed, and if so how do I do it?

tst1.py:
import tst2

tmp = None


def main():
    print(tmp)

    met1()

    print(tmp)


def met1():
    tst2.met2()


def met3():
    global tmp
    tmp = 5


if __name__ == "__main__":
    main()
tst2.py:
import tst1


def met2():
    tst1.met3()
This is just confusing and there most be better way than to solve whatever you try to do.
To fix it,you never call function met1 and met3 function and there is no return or print().
Never use global,don't ask why Wink
import tst2

tmp = None
def main():
    print(tmp)
    print(met1())
    print(tmp)

def met1():
    return tst2.met2()

def met3():
    tmp = 5
    return tmp

if __name__ == "__main__":
    main()
    print(met3())
    print(met1())
import tst1

def met2():
    return tst1.met3()
Output:
None 5 None 5 5
Still Confused
you need to think about how this is getting interpreted, so add a few print statements:
tst1.py:
import tst2
 

tmp = None

print(f'tst1.py -- 1')
def main():
    print(tmp)
    met1()
    print(tmp)

print(f'tst1.py -- 2')
def met1():
    tst2.met2()

print(f'tst1.py -- 3')
def met3():
    tmp = 5

print(f'tst1.py -- 4')
if __name__ == "__main__":
    main()
tst2.py:
import tst1

global tmp
print(f'tst2.py -- 1')

def met2():
    tst1.met3()

print(f'tst2.py -- 2')
output:
Output:
tst1.py -- 1 tst1.py -- 2 tst1.py -- 3 tst1.py -- 4 tst2.py -- 1 tst2.py -- 2 tst1.py -- 1 tst1.py -- 2 tst1.py -- 3 tst1.py -- 4 None None
Notice that tst1.py is loaded twice.

Now if you attempt to print tmp in each one of the print statements just added, program will fail as soon as it tries to import tst2.py because tmp doesn't exist yet!
tst1:
import tst2
 

tmp = None

print(f'tst1.py -- 1, tmp: {tmp}')
def main():
    print(tmp)
    met1()
    print(tmp)

print(f'tst1.py -- 2, tmp: {tmp}')
def met1():
    tst2.met2()

print(f'tst1.py -- 3, tmp: {tmp}')
def met3():
    tmp = 5

print(f'tst1.py -- 4, tmp: {tmp}')
if __name__ == "__main__":
    main()
tst2.py:
import tst1

global tmp
print(f'tst2.py -- 1, tmp: {tmp}')

def met2():
    tst1.met3()

print(f'tst2.py -- 2, tmp: {tmp}')
output:
Output:
tst1.py -- 1, tmp: None tst1.py -- 2, tmp: None tst1.py -- 3, tmp: None tst1.py -- 4, tmp: None
Error:
Traceback (most recent call last): File ".../src/tst1.py", line 1, in <module> import tst2 File ".../src/tst2.py", line 4, in <module> print(f'tst2.py -- 1, tmp: {tmp}') NameError: name 'tmp' is not defined
Bottom line totally avoid globals. This can be done by passing tmp as an argument and returning modifications of tmp
tst1.py:
import tst2
 

print(f'tst1.py -- 1')
def main():
    tmp = None
    print(tmp)
    tmp = met1(tmp)
    print(tmp)

print(f'tst1.py -- 2')
def met1(tmp):
    return tst2.met2(tmp)

print(f'tst1.py -- 3')
def met3(tmp):
    tmp = 5
    return tmp

print(f'tst1.py -- 4')
if __name__ == "__main__":
    main()
tst2.py:
import tst1

print(f'tst2.py -- 1')

def met2(tmp):
    return tst1.met3(tmp)

print(f'tst2.py -- 2')
output:
Output:
tst1.py -- 1 tst1.py -- 2 tst1.py -- 3 tst1.py -- 4 tst2.py -- 1 tst2.py -- 2 tst1.py -- 1 tst1.py -- 2 tst1.py -- 3 tst1.py -- 4 None 5
sorry for double post, I was working on answer when snippsat responded
snippsat's version is cleaner.