myGlobal = "hello" def changeGlobal(): myGlobal="bye"
from first import * changeGlobal() print myGlobal
The output I get is
hello
although I thought it should be
bye
Why doesn't the global variable myGlobal
changes after the call to the changeGlobal()
function?
Globals in Python are global to a module, not across all modules. (Unlike C, where a global is the same across all implementation files unless you explicitly make it static.). If you need truly global variables from imported modules, you can set those at an attribute of the module where you're importing it.
See Python's document on sharing global variables across modules: The canonical way to share information across modules within a single program is to create a special module (often called config or cfg). Import the config module in all modules of your application; the module then becomes available as a global name.
You can access the global variables from anywhere in the program. However, you can only access the local variables from the function. Additionally, if you need to change a global variable from a function, you need to declare that the variable is global. You can do this using the "global" keyword.
Try:
def changeGlobal(): global myGlobal myGlobal = "bye"
Actually, that doesn't work either. When you import *
, you create a new local module global myGlobal
that is immune to the change you intend (as long as you're not mutating the variable, see below). You can use this instead:
import nice nice.changeGlobal() print nice.myGlobal
Or:
myGlobal = "hello" def changeGlobal(): global myGlobal myGlobal="bye" changeGlobal()
However, if your global is a mutable container, you're now holding a reference to a mutable and are able to see changes done to it:
myGlobal = ["hello"] def changeGlobal(): myGlobal[0] = "bye"
I had once the same concern as yours and reading the following section from Norman Matloff's Quick and Painless Python Tutorial was really a good help. Here is what you need to understand (copied from Matloff's book):
Python does not truly allow global variables in the sense that C/C++ do. An imported Python module will not have direct access to the globals in the module which imports it, nor vice versa.
For instance, consider these two files, x.py,
# x.py import y def f(): global x x = 6 def main(): global x x = 3 f() y.g() if __name__ == ’__main__’: main()
and y.py:
# y.py def g(): global x x += 1
The variable x in x.py is visible throughout the module x.py, but not in y.py. In fact, execution of the line x += 1
in the latter will cause an error message to appear, “global name ’x’ is not defined.”
Indeed, a global variable in a module is merely an attribute (i.e. a member entity) of that module, similar to a class variable’s role within a class. When module B is imported by module A, B’s namespace is copied to A’s. If module B has a global variable X, then module A will create a variable of that name, whose initial value is whatever module B had for its variable of that name at the time of importing. But changes to X in one of the modules will NOT be reflected in the other.
Say X does change in B, but we want code in A to be able to get the latest value of X in B. We can do that by including a function, say named GetX() in B. Assuming that A imported everything from B, then A will get a function GetX() which is a copy of B’s function of that name, and whose sole purpose is to return the value of X. Unless B changes that function (which is possible, e.g. functions may be assigned), the functions in the two modules will always be the same, and thus A can use its function to get the value of X in B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With