2

[edit] I renamed testons_constants to testons_variables to make more clear that I want to be able to modify the variables. If in the comment testons_constants appear take in account that it corresponds to the new name testons_variables

I am trying to understand how the variables are shared between files in python.

I made for this purpose three files:

testons.py:

import testons_variables
import testons_functions

# The goal of this file is to understand how python deals with variables shared between files 



print(testons_variables.A) # We can access the variable from the other file
testons_variables.A=5 # We can modify its value
print(testons_variables.A)
testons_functions.fct()
print(testons_variables.A) # The value has been modified from testons_functions

testons_variables.py:

A=0

testons_functions.py

import testons_variables

def fct():
    print(testons_variables.A) # this print will show the value of the variable from testons before the call of the function, and not from
    # testons_variables
    testons_variables.A=50 # We can modify the value
    print(testons_variables.A) 

Here are the outputs when I run testons.py:

0
5
5
50
50

Now, doing "reverse understanding", I realize that wherever the variable testons_variables.A is being modified, it will be modified for all files using it. Indeed, if I modify it in the file testons.py, it will be also modified inside testons_functions.py. And if I modify it in testons_functions.py, it will also be modified for testons.py.

This is my understanding now. So it seems that variables shared between files are modified for everyone, wherever the modification has been done.

What confuses me is that if we use global variable, to modify them within a function we need the keyword "global" to allow the global modification. I never used such keyword here. I know it is not exactly the same situation (I am not using a global variable inside function within a unique file), but I am anyway disturbed by this behavior which makes me think that I am probably missing a point here.

I am then wondering if I understood properly what happens when variable are being shared between files, and this is my question.

StarBucK
  • 209
  • 4
  • 18
  • It is always considered better practice to have variables sent to functions as arguments and returning a value. It would avoid confusion and inconsistencies. Also, you could use `enum` to store constants. @StarBucK – Vishnudev Krishnadas Mar 20 '21 at 17:18
  • @Vishnudev for my current project doing this would be a nightmare as I have many functions in the analog of testons_functions (about 200). Having to explicitely send them the same variable as parameter would imply a huge amount of unnecessary repetition in my code. Now maybe there are other better way to proceed and I am interested to hear about them. But despite this I also would like to check my understanding on this question even if it is "poor way" of writing code =) – StarBucK Mar 20 '21 at 17:22
  • Mutation of objects (such as modules) is visible to anyone with a reference to the object. Assigning names to objects is local (mutates the local `__dict__` of names) unless `nonlocal` or `global` is used to indicate the namespace involved. – Mark Tolonen Mar 20 '21 at 17:23
  • 1
    No. It won't be a repetition, Structure your code properly using a class and it's variables which can be accessed by functions. It would be a debugging nightmare if you follow the global shared variable approach. – Vishnudev Krishnadas Mar 20 '21 at 17:24
  • @StarBucK do you import `testons_constants` in `testons_functions.py` – Ritwik G Mar 20 '21 at 17:26
  • @RitwikG yes I do – StarBucK Mar 20 '21 at 17:27
  • @MarkTolonen I am sorry but I struggle to understand your answer. First question: A module is an external file where you can put some constants or functions (so module here are my two files testons_constants.py, and testons_functions.py). Is that correct ? Then, why are you talking about assining names to objects ? I don't understand why you talk about this. – StarBucK Mar 20 '21 at 17:29
  • @MarkTolonen basically do you agree with my understanding of this code or no ? – StarBucK Mar 20 '21 at 17:30
  • @Vishnudev you are right. My name of the file is probably not good. I modify it in the text but I still have my question =) – StarBucK Mar 20 '21 at 17:39
  • @StarBucK if what you want to achieve is within each file use the initial value of constants from file and make modifications with in that file alone, try modifying import statement to `from testons_constants import A` – Ritwik G Mar 20 '21 at 17:42
  • 1
    https://stackoverflow.com/questions/14323817/global-dictionaries-dont-need-keyword-global-to-modify-them check this out. This should give you some idea why it is happening. – Ritwik G Mar 20 '21 at 17:47

2 Answers2

1

Just print reference of imported teston_variables in both teston.py and teston_functions.py

print(id(testons_variables))

You will notice that both print statements give the same value, so, although they are imported in different places, they use the same reference.

This means that change in one will affect others, as they are pointing to the same memory location.

Now, regarding the usage of global keyword, it is only useful when you need to change the value of a variable and you don't have the scope.

Vishnudev Krishnadas
  • 10,679
  • 2
  • 23
  • 55
0

Modules are objects too. When you define a variable in a module outside the scope of a function, it belongs to the module. It is not global.

When you import a module, you get back the same module object that anyone else who imports the object gets. Python caches modules so that no matter how many times you import it or how many places, you always get only one object containing that module. Because the module is shared, all the variables in that module are likewise shared.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622