Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global variable with imports

Tags:

python

global

first.py

myGlobal = "hello"  def changeGlobal():    myGlobal="bye" 

second.py

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?

like image 998
Joel Avatar asked Jan 16 '11 17:01

Joel


People also ask

Do global variables get imported Python?

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.

How do I share global variables across modules in Python?

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.

Can a global variable be used anywhere?

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.


2 Answers

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" 
like image 173
TryPyPy Avatar answered Oct 07 '22 09:10

TryPyPy


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.

like image 30
wassimans Avatar answered Oct 07 '22 07:10

wassimans