Variables visibility and scope

Reading time10 min

In brief

Article summary

In this article, we discuss variables visibility. This denotes the scope in which variables exist and can be used. In particular, we discuss the difference between local and global variables.

Main takeaways

  • Local variables are only visible in the scope of the function that uses them.

  • Global variables are accessible everywhere in the program.

  • Global variables should be avoided in favor of local variables.

Article contents

As seen in session 1, a variable explicitly associates a name with a value and implicitly occupies space in main memory, the size of which depends on the type of variable. The value currently associated with the variable can be accessed through the variable’s name.

Due to memory limitations, not all variables exist throughout the life of a program. A component of the Python interpreter, called the “garbage collector” deletes variables that cannot be used anymore, and thus frees the memory they occupied.

The visibility of a variable determines its lifetime, and two types of visibility are considered in Python, namely local and global variables.

1 — Local vs. global variables

Local variables are defined inside a function and not accessible outside it.

Example

In this example, we define two variables a and b that are local to function example. They only exist inside example and cease to exist once the function/procedure has returned/completed.

# Example function with two local variables
def example (a):
    b = 2
    print(a, b)

# Call it and try to access variables
example(1)
print(a, b)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is an example function with two local variables
     *
     * @param a An argument of the function.
     */
    public static void example(int a) {
        int b = 2;
        System.out.println(a + " " + b);
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Call it and try to access variables
        example(1);
        System.out.println(a + " " + b);
    }

}

Here is the output we get:

1 2
Traceback (most recent call last):
  File "exaple.py", line 8, in <module>
    print(a, b)
NameError: name 'a' is not defined

Global variables are defined outside all functions and accessible anywhere in the code.

Example

Let’s declare a global variable a, but also a local variable called a, and let’s print these:

# Define a global variable
a = 1

# Example function with a local variable, also named "a"
def example ():
    a = 2
    print(a)

# See what we got
print(a)
example()
print(a)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * Define a global variable (in Java, we use a class-level variable).
     */
    static int a = 1;


    /**
     * Example function with a local variable, also named "a".
     */
    public static void example() {
        int a = 2;
        System.out.println(a);
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // See what we got
        System.out.println(a);
        example();
        System.out.println(a);
    }

}

Here is the output we get:

1
2
1

Note that local variables “hide” global variables with the same name.

2 — The global and nonlocal keywords

Python offers two keywords to play with variables visibility.

The global keyword is used to modify a global variable inside a function.

Example

Let’s adapt the code above, to indicate in example that a is global. Here, the global keyword indicates not to redefine a new variable, but to find an existing one in global memory.

# Define a global variable
a = 1

# Example function
def example ():
    global a
    a = 2
    print(a)

# See what we got
print(a)
example()
print(a)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * Define a global variable (in Java, we use a class-level variable).
     */
    static int a = 1;


    /**
     * Example function.
     */
    public static void example() {
        a = 2;
        System.out.println(a);
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // See what we got
        System.out.println(a);
        example();
        System.out.println(a);
    }

}

Here is the output we get:

1
2
2

The nonlocal keyword is used in nested functions to modify a variable in the enclosing scope. This is quite a cornercase situations, however it can be of use when working with nested functions.

Example

Let’s adapt the code above with a nested function. Note that Java handles scopes differently, and there is thus no equivalent.

# Define a global variable
a = 1

# Example function with a nested function
def example ():
    a = 2
    def inner ():
        nonlocal a
        a = 3
    print(a)
    inner()
    print(a)

# See what we got
print(a)
example()
print(a)

Here is the output we get:

1
2
3
1

Visible local and global variables are stored into two separated data structures (i.e., dictionnaries) that can be displayed calling the locals() and globals() functions, respectively.

Important

In general, it is best to avoid using global variables, as they can be a source of errors. For instance, consider the following function:

# Define a global variable
a = 1

# Example function
def example (b):
    global a
    a += 1
    return a * b

# See what we got
res = example(2)
print(res)
res = example(2)
print(res)
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * Define a global variable (in Java, we use a class-level variable).
     */
    static int a = 1;


    /**
     * Example function.
     *
     * @param b An argument of the function
     */
    public static int example(int b) {
        a += 1;
        return a * b;
    }


    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        int res = example(2);
        System.out.println(res);
        res = example(2);
        System.out.println(res);
    }

}

Calling it twice will lead to two different results (4, then 6), which is not a standard behavior.

To go further

Important

The content of this section is optional. It contains additional material for you to consolidate your understanding of the current topic.

To go beyond

Important

The content of this section is very optional. We suggest you directions to explore if you wish to go deeper in the current topic.

  • name.

    Short description.