python - Using global variables in a function

ID : 126

viewed : 369

Tags : pythonglobal-variablesscopepython





Top 5 Answer for python - Using global variables in a function

vote vote

97

You can use a global variable within other functions by declaring it as global within each function that assigns a value to it:

globvar = 0  def set_globvar_to_one():     global globvar    # Needed to modify global copy of globvar     globvar = 1  def print_globvar():     print(globvar)     # No need for global declaration to read value of globvar  set_globvar_to_one() print_globvar()       # Prints 1 

Since global variables have a long history of introducing bugs (in every programming language), Python wants to make sure that you understand the risks by forcing you to explicitly use the global keyword.

See other answers if you want to share a global variable across modules.

vote vote

85

If I'm understanding your situation correctly, what you're seeing is the result of how Python handles local (function) and global (module) namespaces.

Say you've got a module like this:

# sample.py myGlobal = 5  def func1():     myGlobal = 42  def func2():     print myGlobal  func1() func2() 

You might expecting this to print 42, but instead it prints 5. As has already been mentioned, if you add a 'global' declaration to func1(), then func2() will print 42.

def func1():     global myGlobal     myGlobal = 42 

What's going on here is that Python assumes that any name that is assigned to, anywhere within a function, is local to that function unless explicitly told otherwise. If it is only reading from a name, and the name doesn't exist locally, it will try to look up the name in any containing scopes (e.g. the module's global scope).

When you assign 42 to the name myGlobal, therefore, Python creates a local variable that shadows the global variable of the same name. That local goes out of scope and is garbage-collected when func1() returns; meanwhile, func2() can never see anything other than the (unmodified) global name. Note that this namespace decision happens at compile time, not at runtime -- if you were to read the value of myGlobal inside func1() before you assign to it, you'd get an UnboundLocalError, because Python has already decided that it must be a local variable but it has not had any value associated with it yet. But by using the 'global' statement, you tell Python that it should look elsewhere for the name instead of assigning to it locally.

(I believe that this behavior originated largely through an optimization of local namespaces -- without this behavior, Python's VM would need to perform at least three name lookups each time a new name is assigned to inside a function (to ensure that the name didn't already exist at module/builtin level), which would significantly slow down a very common operation.)

vote vote

79

You may want to explore the notion of namespaces. In Python, the module is the natural place for global data:

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.

A specific use of global-in-a-module is described here - How do I share global variables across modules?, and for completeness the contents are shared here:

The canonical way to share information across modules within a single program is to create a special configuration module (often called config or cfg). Just import the configuration module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere. For example:

File: config.py

x = 0   # Default value of the 'x' configuration setting 

File: mod.py

import config config.x = 1 

File: main.py

import config import mod print config.x 
vote vote

62

Python uses a simple heuristic to decide which scope it should load a variable from, between local and global. If a variable name appears on the left hand side of an assignment, but is not declared global, it is assumed to be local. If it does not appear on the left hand side of an assignment, it is assumed to be global.

>>> import dis >>> def foo(): ...     global bar ...     baz = 5 ...     print bar ...     print baz ...     print quux ...  >>> dis.disassemble(foo.func_code)   3           0 LOAD_CONST               1 (5)               3 STORE_FAST               0 (baz)    4           6 LOAD_GLOBAL              0 (bar)               9 PRINT_ITEM                        10 PRINT_NEWLINE           5          11 LOAD_FAST                0 (baz)              14 PRINT_ITEM                        15 PRINT_NEWLINE           6          16 LOAD_GLOBAL              1 (quux)              19 PRINT_ITEM                        20 PRINT_NEWLINE                     21 LOAD_CONST               0 (None)              24 RETURN_VALUE         >>>  

See how baz, which appears on the left side of an assignment in foo(), is the only LOAD_FAST variable.

vote vote

59

If you want to refer to a global variable in a function, you can use the global keyword to declare which variables are global. You don't have to use it in all cases (as someone here incorrectly claims) - if the name referenced in an expression cannot be found in local scope or scopes in the functions in which this function is defined, it is looked up among global variables.

However, if you assign to a new variable not declared as global in the function, it is implicitly declared as local, and it can overshadow any existing global variable with the same name.

Also, global variables are useful, contrary to some OOP zealots who claim otherwise - especially for smaller scripts, where OOP is overkill.

Top 3 video Explaining python - Using global variables in a function







Related QUESTION?