I have 2 files let say them a.py
and b.py
, b.py
has a global variable let say test
(data type is a string), and I’m importing test
in a.py
. Now, during runtime, a function in a.py
calls a function of b.py
, and that function changed the value of test
in b.py
but this change doesn’t show in a.py
because the test is of string datatype and string is immutable.
I tried using the list, and it works, but I’m not feeling very good about using a list with one element in it. So, is there any mutable data type(similar to string) that I can use for this purpose?.
Code when the test
is string.
b.py
test = "hello"
def changeTest():
global test
test = "hii"
a.py
from b import test,changeTest
def callFunctionInB():
changeTest()
print(test)
callFunctionInB()
print(test)
output:
hello
hello
Code when the test is list.
b.py
test = ["hello"]
def changeTest():
test[0] = "hii"
a.py
from b import test,changeTest
def callFunctionInB():
changeTest()
print(test)
callFunctionInB()
print(test)
output:
['hello']
['hii']
Python import statements are extremely tricky, and your issue is because of poor usage of import statements.
from ... import ...
creates a copy of imported variable for reference. To validate this on your copy of python, try running:
### a.py
import b
from b import string_value, change_value
print(string_value)
change_value("new value")
print(string_value)
print("a.py ==> b.string_value = \t", id(b.string_value))
print("a.py ==> string_value = \t", id(string_value))
### b.py
string_value = "previous"
def change_value(given_value):
global string_value
print("b.py ==> 'global' string_value \t", id(string_value))
string_value = given_value
Import statement in a.py
is creating a copy of the variable for itself, so when you update the global variable of module b, it has no effect on the variable in a.
To answer your question, there are a couple of possibilities:
from ... import ...
.
Example of this would be:### a.py
import b
print(b.string_value)
b.change_value("new value")
print(b.string_value)
### b.py
string_value = "previous"
def change_value(given_value):
global string_value
string_value = given_value
Use a third c.py
configuration file or even better create a class for your use case with complete getters and setters. This is the best approach. Follow this approach for clean and maintainable code base. Lots of other SO answers have good documentation around this. Like Using global variables between files?
If you absolutely have to use from ... import ...
, you can use an ugly update syntax. Please avoid this at all costs. One of the above two things should be easily feasible. For your reference, sample code to do this would be:
### a.py
from b import string_value, change_value
print(string_value)
change_value("new value")
print(string_value)
### b.py
# Please don't use this code except for understanding purpose
import sys
string_value = "previous"
def change_value(given_value):
sys.modules['__main__'].string_value = given_value