TransWikia.com

Python global variables unexpected behavior

Stack Overflow Asked by user118967 on January 16, 2021

I am finding a discrepancy I did not expect in the Python (3.8) example below.

We define a global variable in module config:

config.py:

global_variable = 80

Then two functions in module foo using that global variable in two different ways that I expected to be equivalent:

foo.py:

from config import global_variable
import config

def foo1():
    return global_variable


def foo2():
    return config.global_variable

Finally, I print the result of both functions after setting the global variable to 0 in a main script:

main.py:

import config
import foo

if __name__ == '__main__':
    config.global_variable = 0
    print("foo1(): ", foo.foo1())
    print("foo2(): ", foo.foo2())

but I find them to have different results. The output is:

foo1():  80
foo2():  0

How is that difference explained?

3 Answers

Thank you for the previous answers and comments. They helped me understand the issue but I feel that none of them is completely clear, so here is an answer.

When I asked the question, I though that from config import global_variable would create a new binding (or "name") global_variable in the local package, but which would still bind to the same memory location as config.global_variable (two names for the same variable).

However, what seems to be true is that from config import global_variable creates a new variable global_variable in the local package, merely initialized by the value of config.global_variable. (To be more precise, for efficiency reasons global_variable probably still points to the same memory location as config.global_variable when it is created but, unlike a normal binding, it starts referring to some other memory location when assigned a new value).

For this reason, when I assign a new value to global_variable, I do not affect config.global_variable as originally expected, but instead change the value of the new variable global_variable.

So it seems that if I want a variable to be used across modules, I must always use the qualified form config.global_variable in all of them.

Correct answer by user118967 on January 16, 2021

It's the way you used your import statements. You imported the same file twice in different manners so python also treats them as two imports. So when you change the value for the variable as

config.global_variable = 0 

It affects the global variable of

import config

this import statement in your foo.py file.

from config import global_variable
import config

def foo1():
    return global_variable # uses from config import global_variable statement


def foo2():
    return config.global_variable # uses import config

Hence in here, foo2() returns the changed variable's value but foo1() returns the original. If you want to change foo1()'s value then you must do something like this.

from config import global_variable
import config
import foo

if __name__ == '__main__':
    config.global_variable = 0
    global_variable = 0
    print("foo1(): ", foo.foo1())
    print("foo2(): ", foo.foo2())

Answered by IsharM on January 16, 2021

I'm probably just as new at this as you are, but I'm pretty sure a variable is only global if the global declaration is in the script you're importing to

Answered by Calvin Chaplow on January 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP