1

I am new to python and trying to update a variable, say x, in an imported module and then trying to use the updated variable x in other variable, say y, but y uses the old value of x instead of the new value. Please help provide some pointers to make it work!

My intention is to use a py file to list all global variable which I can use them in other py files. I could update a global variable and use it but not sure how to use an updated global variable in other variables.

Sample code:

a.py:

var1 = 0
var2 = var1 + 1

b.py:

import a

def update_var():
    a.var1 = 10
    print("Updated var1 is {}".format(a.var1))
    print("var2 is {}".format(a.var2))

if __name__ == "__main__":
    update_var()

Output:

Updated var1 is 10
var2 is 1

Expected Output:

Since i am updating var1 to 10, i am expecting that the updated value be used in var2

Updated var1 is 10
var2 is 11
1

3 Answers 3

3

Python doesn't work that way. When you import a module, the code in the module is executed. In your case, that means two variables are defined: a.var1 with value 0 and a.var2 with value 1. If you then modify a.var1, you won't affect a.var2, its value was defined when you imported the module and it won't change unless you explicitly alter it.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for you quick response. i observed this behavior. When i re-import, variables get reverted to original values. But how to over come this? How to make persistent changes to modules which have global variables? I have a use case where i will maintain all global variable in a separate file and few variable depend on other variable values, like the one in my sample code(var2 = var1 + 1). Any suggestions?
Yes, my suggestion is to not store global variables in a module, as you already saw that doesn't work as you'd like it to. If you have dependencies on the variables, you could define a Globals class that has properties (note: not fields, but actual properties) in which the setters take care of updating the related variables as needed. You could ten apply something similar to a Singleton pattern to generate only one instance of the class and pass the same instance where needed. Note that, depending on your specific use-case, this may or may not work.
1

This is due to var2 being initialized only once whilst importing. The way around this would be to write a getter or and update function.


A possible getter function would be:

a.py

var1 = 0
var2 = var1 + 1

def getVar2():
    return var1 + 1

b.py:

import a

def update_var():
    a.var1 = 10
    print("Updated var1 is {}".format(a.var1))
    print("var2 is {}".format(a.getVar2()))

if __name__ == "__main__":
    update_var()

A possible update function would be:

a.py

var1 = 0
var2 = var1 + 1

def updateVar2():
    var2 = var1+1

b.py:

import a

def update_var():
    a.var1 = 10
    a.updateVar2()
    print("Updated var1 is {}".format(a.var1))
    print("var2 is {}".format(a.var2()))

if __name__ == "__main__":
    update_var()

1 Comment

thanks for your quick response. But your solution cannot be used when there are many variables that depend on each other. like var2 = var1 +1, there can be many other variables that use var1, say var3 = var2 +1, var4 = var2 + var2 etc... Also the getter or update function just return some values but not update the module variables.
0

Based on the inputs from @GPhilo and my personal experiences i came up with below working solutions, guess solution 2 is more pythonic.

Solution 1:

a.py:

class Globals:

def __init__(self, value):
    self.var1 = value
    self.var2 = self.var1 + 1

b.py:

from a import Globals

def update_var():
    globals_instance = Globals(10)
    print("Updated var1 is {}".format(globals_instance.var1))
    print("var2 is {}".format(globals_instance.var2))


if __name__ == "__main__":
    update_var()

Output:

Updated var1 is 10
var2 is 11

Solution 2:

Change implementation of a.py as below"

a.py:

class Globals:

    def __init__(self, value):
        self._var1 = value
        self.var2 = self._var1 + 1


    @property
    def var1(self):
        return self._var1


    @var1.setter
    def var1(self, value):
        self._var1 = value

Comments

Your Answer

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.