Global variables


Martin McBride, 2018-03-06
Tags scope global global variable
Categories python language intermediate python

In this article we will look at the issues around using global variables in Python, the use of the global keyword, and an alternative (and better) method of implementing global data.

Global variables

You may have heard people say that you should never use global variables. It is certainly true that in a large, complex program, misuse of global variables can cause a lot of problems. But if you have ever written a simple Python script, you will most certainly have used global variables already.

A global variable is a variable that is defined outside of any function. Here is an example of a global variable:

a = 10
print('Global a =', a)

The variable a is automatically treated as global because it is created outside of any function. The print function prints:

Global a = 10

Local variables

A local variable, by contrast, is defined within a function. Here is an example of a local variable:

def show():
    b = 20
    print('Local b =', b) #1

show()
print('Try to access b outside the show function:', b)  #2

The first print statement, #1, executes when the show function is called. As you might expect it prints

Local b = 20

The second print statement, #2, executes after the show function has returned. At the point, the variable b doesn't even exist. It is only defined locally, inside the function. So you get an error message:

NameError: name 'b' is not defined

Reading a global variable inside a function

As we have just seen, you can't access a local variable outside of the function where it is defined. But you can access global variables from anywhere in your code, including inside a function.

If you only want to read the value of a global variable, you can just go a head and do it:

a = 10

def show():
    print('Global a =', a) #1

show()

Here the first print references variable a. Python first checks is there is a local variable a. There isn't one, so it looks for a global variable a instead, and uses that. It prints

Global a = 10

Writing a global variable from inside a function

Now what if you wanted to change the value of a? In that case you must tell Python that the variable a you are accessing within the show function is intended to be the global variable a (otherwise Python might try to create a local variable instead). You do this with the global keyword. Notice that the global statement is used inside the function:

a = 10

def show():
    global a
    a = 30
    print('Global a =', a) #1

show()
print("Global a now equals", a) #2

Print statement #1 prints:

Global a = 30

and print statement #2 prints:

Global a now equals 30

proving that we have indeed changed the value of the global a.

Why is a global declaration needed?

So why do we need the global keyword? Consider this code:

a = 10

def show():
    a = 30
    print('Local a =', a) #1

show()
print("Global a now equals", a) #2

The problem here is that Python sees a = 30 and creates a local variable a that hides the global variable with the same name. It sets the local variable to 30. The print statement #1 then prints:

Local a = 30

After we leave the function, the local variable ceases to exists. The global a hasn't changed, so we get:

Global a now equals 10

What if we tried to trick Python, by using the variable a before we try to set its value:

def show():
    print('Local a =', a) #1
    a = 30

You might think that Python would be forced to use the global a in the print statement (because a hasn't been defined locally yet), and then it would somehow carry on using the global a for the rest of the function. It doesn't! That would be a recipe for confusion. The rule is:

If a variable is assigned to anywhere within the body of a function, a local variable will be created unless the global keyword is used to override it.

In the case above, a would definitely be a local variable, and because we are trying to print it before it has been assigned, you will get an error.

A better way

If you think this all sounds quite messy, you are quite right. It is fine for a simple script, but if you are writing a large program using global is a recipe for error.

A better approach is to use a separate module for your global variables. A module is simply a file containing Python code. So you can create a module called globals (for example) simply by creating a file called globals.py, with the following code:

a = 10
b = 5

You should save globals.py in the same folder as your main file (this is the first place Python looks for modules). You then simply need to import globals into your main file. The variables can be accessed using globals.a etc. Here is the code:

import globals

def show():
    a = 30
    b = 20
    print(a)
    print(globals.a)
    print(b)
    print(globals.b)
    globals.a = globals.a + 1

show()
print(globals.a)
print(globals.b)

This make it crystal clear whether you are dealing with a global or local variable. It also has the advantage of defining all your globals in one place so that you can keep track of them.

If you found this article useful, you might be interested in the book Python Quick Start or other books by the same author.

Prev

Popular tags

2d arrays abstract data type alignment and animation arc array arrays behavioural pattern bezier curve built-in function callable object chain circle classes close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data types design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path pattern permutations polygon positional parameter print pure function python standard library radial gradient range recipes rectangle recursion reduce repeat rgb rotation scaling sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency triangle tuple turtle unpacking user space vectorisation webserver website while loop zip