Local and Global Variables

Variable Scope

Python has 4 scopes: local, enclosing, global, and built-ins. Python's "global" variables are only global to the module they're in. The only truly universal variables are the built-ins.

0%
Watch other topic trails

Transcript:

Let's talk about local and global variables in Python.

Reading global variables

We have a variable here called message, which points to the string Hello world:

>>> message = "Hello world"

We also have a function called see_message, which prints out the message variable.

>>> def see_message():
...     print(message)
...

When we call see_message, we'll see Hello world printed out:

>>> see_message()
Hello world

The message variable is a global variable. It is defined at the global scope, meaning it's defined outside of any function; it's defined at the module level.

Assigning to local and global variables

Python also has local variables. Local variables are defined inside of a function, and they only exist inside that function. The arguments given to a function are an example of local variables.

You can read from global variables, as we did above in our see_message function. But can you write to global variables?

Let's take a function call set_message that accepts a name argument and assigns the message variable to Hello and the given name. The function will then print out the message variable:

>>> def set_message(name):
...     message = f"Hello {name}"
...     print(message)
...

When we call set_message with Trey, it prints out Hello Trey:

>>> set_message("Trey")
Hello Trey

What do you think the global message variable is at this point? Is it Hello world or is it Hello Trey?

It turns out that the global variable message variable is still Hello world:

>>> message
'Hello world'

Assigning to a variable inside a function always assigns to a local variable.

Variable shadowing

You can read from a global variable and you can read from a local variable, but when you write to a variable inside a function, you're writing to a local variable.

If you have two variables of the same name, for example a global variable called message and a local variable called message, it's the local variable that wins when you read from that variable.

Creating a local variable with the same name is a global variable is called shadowing a variable and it's not usually a good idea, but it is possible to do in Python.

Within a function, each variable is either local or global

When you have two variables of the same name, a global variable, and a local variable, inside your function, that variable name will always be either global or local. One variable cannot be both global and local inside the same function.

Let's modified the set_message function here to print out message before we assign to it and then we print out message again afterward:

>>> def set_message(name):
...     print(message)
...     message = f"Hello {name}"
...     print(message)
...

When we call set_message this time, you might assume that it's going to print out the global message variable (Hello world) and then assign to the local message variable, and then print out the local message variable (Hello Trey):

>>> set_message("Trey")

But that's not what happens:

>>> set_message("Trey")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in set_message
UnboundLocalError: local variable 'message' referenced before assignment

Instead, Python raised an exception. The exception notes that the local variable message was referenced before assignment. It's giving us that error on the first line of code in set_message function, where we first tried to read from message.

When we defined the set_message function, Python parsed the code for our function, looked at all the assignment statements, and then kept track of the variable names we were assigning to ( message in this case) and identified those variable names as being local variables.

So that message variable cannot be treated as a global variable. It's local for the entirety of the function, even before we've defined it.

This happened because we're assigning to message within the function. Python knows that you can assignment statements write to local variables so any assignment statements in our function will indicate to Python that a specific variable name is a local variable name within the entirety of that function.

Summary

In Python, you can read from global variables, and you can read from or write to local variables, but inside a function, every variable is either local or global within that function. This might seem odd, but it's a useful feature because it would be really confusing if a variable could switch from being a global variable to being a local variable within one function.

But the biggest takeaway is that when you write to a variable within a function, you're always writing to a local variable.