简体   繁体   中英

Python Global Variable Import

Let's say I have a config.py file that stores a global variable that will be used in multiple modules (in the same package):

# pkg/config.py
GLOBAL_VAL = 4
# pkg/module_A.py
from . import config

def func_A(x):
    return config.GLOBAL_VAL * x
# pkg/module_B.py
from . import config

def func_B(x):
    return config.GLOBAL_VAL + x

And then, I have a main.py that might call these functions:

# main.py

from pkg import module_A, module_B

x = 5
module_A.func_A(x)
module_B.func_B(x)

# Prints:
# 20
# 9

This is fine. However, there are times when a user may want to change GLOBAL_VAL and it seems like the natural thing to do is to import it and then set the value:

# main.py

from pkg import module_A, module_B
from pkg.config import GLOBAL_VAL

GLOBAL_VAL = 100
x = 5
print(module_A.func_A(x))
print(module_B.func_B(x))

# Prints:
# 20 
# 9

However, I expected this to print 500 and 105 and not 20 and 9 . It appears that the import is "local" and does not affect config.GLOBAL_VAL and so the only way to accomplish what I want is by doing:

# main.py

from pkg import module_A, module_B
from pkg from config

config.GLOBAL_VAL = 100
x = 5
print(module_A.func_A(x))
print(module_B.func_B(x))

# Prints:
# 500 
# 105

My question is if there is some way to allow both from pkg.config import GLOBAL_VAL AND from pkg from config to work?

Explanation of What's Happening

from pkg.config import GLOBAL_VAL

This line assigns the name GLOBAL_VAL in the top-level scope to the value bound to the property GLOBAL_VAL of the module pkg.config . Any subsequent assignments to the name GLOBAL_VAL will actually only change the value that is bound to that name in the top-level scope ( pkg.config.GLOBAL_VAL will remain unchanged).

Using global keyword actually will still not help you here, because global causes all references to the name in the global assignment to refer to the name bound in the top-level scope. Since we're already in the top-level scope, it effectively does nothing.

The only way to change the property called GLOBAL_VAL of pkg.config is to gain reference to the pkg.config object and then assign a new value to it's GLOBAL_VAL property.

Answer

No, with from pkg.config import GLOBAL_VAL , it is not possible to mutate the value of pkg.config.GLOBAL_VAL by assigning a new value to the name GLOBAL_VAL . It's similar to how if I have a dictionary d = {'a': 2} , I can't change the value of d['a'] by doing:

v = d['a']
v = 3
print(d['a']) # still prints 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM