Using global variables in a function

3,700,170

Solution 1

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 it's unclear whether globvar = 1 is creating a local variable or changing a global variable, Python defaults to creating a local variable, and makes you explicitly choose the other behavior with the global keyword.

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

Solution 2

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.)

Solution 3

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

Solution 4

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.

Solution 5

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.

Share:
3,700,170
user46646
Author by

user46646

Updated on August 04, 2022

Comments

  • user46646
    user46646 almost 2 years

    How can I create or use a global variable in a function?

    If I create a global variable in one function, how can I use that global variable in another function? Do I need to store the global variable in a local variable of the function which needs its access?

  • Anthony
    Anthony over 11 years
    It's extreme exaggeration to refer to globals as "so dangerous." Globals are perfectly fine in every language that has ever existed and ever will exist. They have their place. What you should have said is they can cause issues if you have no clue how to program.
  • Fábio Santos
    Fábio Santos over 11 years
    I think they are fairly dangerous. However in python "global" variables are actually module-level, which solves a lot of issues.
  • barlop
    barlop over 10 years
    thanks, i'm new to python, but know a bit of java. what you said worked for me. and writing global a<ENTER> within the class.. seems to make more sense to me than within a function writing 'global a'.. I notice you can't say global a=4
  • swdev
    swdev over 9 years
    This is probably the simplest yet very useful python trick for me. I name this module global_vars, and initialize the data in init_global_vars, that being called in the startup script. Then, I simply create accessor method for each defined global var. I hope I can upvote this multiple times! Thanks Peter!
  • spazm
    spazm about 9 years
    'in every function you want to use' is subtly incorrect, should be closer to: 'in every function where you want to update'
  • jtlz2
    jtlz2 about 9 years
    What if there are many many global variables and I don't want to have to list them one-by-one after a global statement?
  • Martijn Pieters
    Martijn Pieters almost 9 years
    The heuristic looks for binding operations. Assignment is one such operation, importing another. But the target of a for loop and the name after as in with and except statements also are bound to.
  • watashiSHUN
    watashiSHUN over 8 years
    You mentioned that the namespace decision happens at compile time, I don't think it is true. from what I learn python's compilation only checks for syntax error, not name error try this example def A(): x+=1, if you don't run it, it will not give UnboundLocalError, please verify thank you
  • oHo
    oHo almost 7 years
    What is the advantage to move the global variables to another file? Is it just to group together the global variables in a tiny file? And why using the statement import ... as ...? Why not just import ...?
  • oHo
    oHo almost 7 years
    Ah... I have finally understood the advantage: No need to use the keyword global :-) => +1 :-) Please edit your answer to clarify these interrogations that other people may also have. Cheers
  • vladosaurus
    vladosaurus over 6 years
    for a reason I don't like the config.x can I get rid of it? I came with x = lambda: config.x and then I have the new value in x(). for some reason, having a = config.x does not do the trick for me.
  • Vassilis
    Vassilis over 6 years
    It is common to use a capital letter for global variables like MyGlobal = 5
  • BlackJack
    BlackJack over 6 years
    @watashiSHUN: The namespace decision does happen at compile time. Deciding that x is local is different from checking at runtime if the local name was bound to a value before it is used the first time.
  • BlackJack
    BlackJack over 6 years
    @Vassilis: It is common to upper case all letters: MY_GLOBAL = 5. See the Style Guide for Python Code.
  • jhylands
    jhylands over 5 years
    @vladosaurus does from config import x solve that?
  • Clément
    Clément about 5 years
    globals() always returns globals available in the local context, so a mutation here may not reflect in another module.
  • Paul Uszak
    Paul Uszak over 4 years
    Absolutely re. zealots. Most Python users use it for scripting and create little functions to separate out small bits of code.
  • fpaekoaij
    fpaekoaij over 4 years
    Cool, but what to do if I want to create a global variable inside a function inside a class and want to use that variable inside another function inside another class? Kinda stuck here
  • Russia Must Remove Putin
    Russia Must Remove Putin over 4 years
    @anonmanx I don't know why you're stuck, it's the same behavior in a method as in a regular function. But I'll update my answer with your remark and some demo code, ok?
  • fpaekoaij
    fpaekoaij over 4 years
    okay, got it. So I will have to explicitly call that function for using that global variable.
  • Robert
    Robert over 4 years
    @MartijnPieters For the name after as in an except clause this wasn't obvious to me. But it gets auto-deleted to save memory.
  • Martijn Pieters
    Martijn Pieters over 4 years
    @Robert: not to save memory, but to avoid creating a circular reference, which can lead to memory leaks. That's because an exception references a traceback, and the traceback references every local and global namespace along the whole call stack, including the as ... target in the exception handler.
  • not2qubit
    not2qubit over 3 years
    Congratulations! Finally someone who got the most important point of using global. Namely using a variable in a function that was defined after the function itself.
  • SHIVAM SINGH
    SHIVAM SINGH about 2 years
    global_var is a global variable and all functions and classes can access that variable. The func_1() accessed that global variable using the keyword global which means to point to the variable which is written in the global scope. If I didn't write the global keyword the variable global_var inside func_1 is considered a local variable which is only usable inside the function. Then inside func_1 I have incremented that global variable by 1. The same happened in func_2(). After calling func_1 and func_2, you'll see the global_var is changed.