Reputation: 6899
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?
Upvotes: 2
Views: 1966
Reputation: 41
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.
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
Upvotes: 4