I often have variables in my Python projects that I need to share between modules. I know this can be done with args to function calls, but sometimes, it's more convenient to create a single global_vars.py module, and add any variables that need to be shared there, which is what I often end up doing. These variables can then be imported from any other module, and easily shared. This generally works fine for me. Sometimes though, some unexpected stuff happens.
Ex:
I have 3 files:
main.py:
from global_vars import var
from mod import modify_variable
print(f"{hex(id(var))} - address of var in main module after import")
modify_variable()
print(f"{hex(id(var))} - address of var in main module after modify_variable() call")
global_vars.py:
var = 'hi'
print(f"{hex(id(var))} - address of var during import")
mod.py: from global_vars import var
def modify_variable():
global var
print(f"{hex(id(var))} - address of var before modifying it in modify_variable()")
var = 'hello'
print(f"{hex(id(var))} - address of var after modifying it in modify_variable()")
If you run main.py with Python3, you get output that looks like this:
0x7f0f993bb7f0 - address of var during import
0x7f0f993bb7f0 - address of var in main module after import
0x7f0f993bb7f0 - address of var before modifying it in modify_variable()
0x7f0f993bb870 - address of var after modifying it in modify_variable()
0x7f0f993bb7f0 - address of var in main module after modify_variable() call
Basically, everything behaves as expected until we call modify_variable.
Within modify_variable, the address of var starts out as we expect.
Then we assign a new string to it. This does a few things:
- It creates a brand new string in memory
- It changes
varto point to the address of this new string - The garbage collector would presumably, at some point, clean up the old string's address
Given this, I would expect that the last check of the address of var would also point to the address of the new string. Therefore, I would expect the result to look like this:
0x7f0f993bb7f0 - address of var during import
0x7f0f993bb7f0 - address of var in main module after import
0x7f0f993bb7f0 - address of var before modifying it in modify_variable()
0x7f0f993bb870 - address of var after modifying it in modify_variable()
0x7f0f993bb870 - address of var in main module after modify_variable() call
but it doesn't. var within modify_variable, and var within main.py now point to completely different addresses, and can no longer share the same data.
What happened? From what I've read, if I hadn't used global var in mod.py, it was possible that I would have created a local variable with the same name as the global var variable, which could cause the symptoms above, but using global var as I do ensures I'm dealing with global_vars.var, doesn't it?