3

I have three files: bar.py, foo.py, and main.py.

# bar.py
import numpy as np
global y
x=0
y=0
z=np.array([0])
# foo.py
from bar import *
def foo():
    x=1
    y=1
    z[0]=1
# main.py
from foo import *
from bar import *
print(x,y,z)
# 0 0 [0]
foo()
print(x,y,z)
# 0 0 [1]

Question: Why did x and y not change their values while z did change value of its element? And, how should I write so that I can change values of x and y, which can also be accessible from other files?

Normally I'd never write in this fashion, which was forced when translating an archaic FORTRAN77 program into python.

The original code heavily uses common blocks and includes, so basically I cannot trace the declarations of all variables. But still I wanted to preserve the original style of the code, so I tried to make a "global variables module", whose variables can be modified from any part of the program.

Back to my question, my guess is that numpy.ndarray is just pointer, and we do not change the value of a pointer, so z has changed. But even then the behavior of z seems very dangerous, that I cannot trust z to be shared as a global variable and its value is the same across all files. Who knows that z in main and foo are pointing the same memory sector?

Moreover, how can I make some variables truly global? Actually when I tried to translate that FORTRAN program, I tried to make class and instances of them, then pass the instance over the arguments of the function, then I realized that requires modifying the code tremendously.

What can I do?

Hojin Cho
  • 384
  • 2
  • 12
  • Because you *reassigned* X and y, but you *mutated* z. This are different actions. – Daniel Roseman Mar 22 '18 at 16:41
  • 2
    Note, **all** objects have exactly the same behavior in Python, what you are referring to as being "only a pointer". You should read https://nedbatchelder.com/text/names.html. Note, Python does not support truly global variables, only module global variables. but you can import the module and modify the module namespace and this can simulate real global variables. – juanpa.arrivillaga Mar 22 '18 at 16:46
  • See: [Use of “global” keyword in Python](https://stackoverflow.com/questions/4693120). – hpaulj Mar 22 '18 at 20:54
  • Years ago I converted a fortran program into MATLAB. Initially all those commons were arrays in the main workspace. Gradually I packed them into cells and structs, and eventually into the new class system. – hpaulj Mar 22 '18 at 20:56
  • Thanks to all the comments. I should look up juanpa suggested, but eventually it’d be better to organize them into some objects or something. – Hojin Cho Mar 24 '18 at 02:24

1 Answers1

0

You imported the variables and worked with your local copies. x and y are integers, immutable types, and are therefore assigned locally. However, when you worked with z, you reached into a mutable type and altered an element thereof.

If you want to change the package variables (in the original package), then you need to import the package itself and alter those values:

# foo.py
# from bar import *
import bar
def foo():
    bar.x=1
    bar.y=1
    bar.z[0]=1


# main.py
from foo import *
import bar
print(bar.x,bar.y,bar.z)
# 0 0 [0]
foo()
print(bar.x,bar.y,bar.z)
# 0 0 [1]

Output:

0 0 [0]
1 1 [1]
Prune
  • 76,765
  • 14
  • 60
  • 81