1

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']
asked Apr 1, 2021 at 20:06

2 Answers 2

1

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:

  1. Use module level import. Don't use 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
  1. 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?

  2. 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
answered Apr 2, 2021 at 7:49

1 Comment

Woah, Thanks, it worked. I understood the mistake I was making. I currently shifted to suggestion 1.
0

I believe your problem lies solely with the implementation of b.py. In that given:

test = ["hello"]
def changeTest():
 test[0] = "hii"

the variable test within the changeTest function is defined locally, not globally. By using: test = "hello"

def changeTest():
 global test
 test = "hii"

You will directly update the global variable test.

answered Apr 1, 2021 at 21:50

1 Comment

I got your point. But even after making the test global in the changeTest it's not working. I also updated the code for clarity.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.