Local and global variables, scope and Python
Introduction
When we use a variable in a programming language, we need to understand something called scope, and whether the variable we are using is local or global. If a programmer doesn't understand the idea of scope, they will sooner or later either get an error message popping up or they will get a logic error in their code. A logic error is where the code runs and 'works' but produces an unexpected result. These are often the hardest type of errors to track down so it is a much better idea to understand scope than trying to deal with problems that are caused by a lack of understanding of this concept.
Local variables
In Python, local variables are any variables which are changed or created anywhere inside a function. The variable is only available inside that function. A program cannot access local variables outside of the function. A program cannot use the values held in local variables outside of the function. Indeed, the moment the program flow leaves a function, the local variables inside the function actually disappear completely, never to be seen again!
Global variables
Global variables in Python are created and used somewhere in the main program but outside of all functions. These variables can be used and modified outside of all functions but importantly, they can also be used and modified in all functions as well.
Turning a local variable into a global variable
Sometimes, we want to turn a local variable into a global variable and we will see this in action in an example later. We can do this in python using the keyword global.
Scope
We use the term scope when talking about whether variables are local or global. We talk about the scope of the variable. This means we want to know whether a variable is only available inside a particular function, or whether it is available in the main program and all of the functions as well.
Should a programmer use local or global variables?
Generally speaking, programmers should avoid using global variables wherever possible.
-
- If we write a function, and we want to put it in a library to use in other programs, it is almost impossible to do if we use global variables in it. This is because any program we use the function in in the future will need to have exactly the same global variables in it as the original program, and they will have to be used in exactly the same way.
- Using global variables makes it much harder to track down bugs.
- We want to write code using self-contained blocks of code wherever possible, not code that has sub-routines or functions, which have to go and collect global values from the main program all the time.
- Another issue with global variables is that they always exist in memory. Local variables disappear as soon as you leave a function and the memory they used is returned to the main area so it can be used for other things. Programs always have to keep global variables and that means programs that require more memory than ones that used local variables.
Some examples to illustrate local and global variables and the scope of a variable
The first thing to show is that local variables cannot be accessed outside of the function that it was created in. Type in the following code and run it.
def scope():
message = "Peter Rabbit"
print (message)
scope()
print (message)
When you ran the code, the program called the function 'scope'. The variable called 'message' was assigned the value 'Peter Rabbit'. We know that if you create or modify a variable anywhere inside a function, it becomes a local variable. This local variable was then printed out and the function exited. We are now back in the global scope of the program. The last line of the function tries to print the contents of the variable 'message' but an error message is generated. This is because when we exited the function, all local variables that were inside that function disappeared. The program cannot find a variable called 'message' so tells you that it isn't defined.
Modify your program so that it looks like the following program:
def scope():
print (message)
message = "Peter Rabbit"
scope()
All scope does in this program is to print whatever the variable 'message' holds. When you enter the function, is the variable local or global? The answer to this lies in what we said earlier, that in Python, if you create or change a variable anywhere inside a function, then it becomes a local variable. We haven't created or changed the variable inside the function. We have only used the variable inside the function. We are therefore using the global variable called 'message'.
Let's change the program to this:
def scope():
message = "Lily Bobtail"
print (message)
message = "Peter Rabbit"
scope()
print (message)
When we run this code, what happens now? We set our variable to hold 'Peter Rabbit' in the main program so this is a global variable. Then we called the function. When we entered the function, however, the first thing we did was to set a variable called 'message' to hold 'Lily Bobtail'. According to what we said earlier, if we create or change a variable anywhere inside a function, it becomes a local variable. We also said that when you leave the function, all local variables in that function disappear! So what should get printed out? Try it and see. You should see that 'Lily Bobtail' gets printed first. When the function exits, all local variables in that function disappear. The program then gets to the last line of the program and we print 'Peter Rabbit'. The local variable called 'message' was a completely different variable to the global variable called 'message' even though they had the same name!
Now let's try and print the global variable and the local variable from the function. Modify your code to this:
def scope():
print (message)
message = "Lily Bobtail"
print (message)
message = "Peter Rabbit"
scope()
What we have done is to set a global variable called 'message' to hold 'Peter Rabbit'. Then we called the function. The first thing we did in the function was to try and print the variable's contents. Then we tried to change the variable so it holds 'Lily Bobtail'. Finally, we tried to print the contents of the variable again. What do you think would happen now? Run the code and see. You should see that you get an error message, telling you that you are trying to use a variable before referencing it. What is happening here?
When the variable was set in the main program to 'Peter Rabbit', it was a global variable. When we called the function, the first thing we tried to do in the first line was to print the variable. But there is a problem! According to what we have said a few times now, if we try to create or change a variable anywhere inside a function, it becomes a local variable. So when we changed the variable to 'Lily Bobtail' later on in the function, that meant that the variable 'message' inside the function was local. Now, even though we did this after the first line in the function, the first line is a problem because we are now trying to use a local variable before we have actually created it. That's why an error message pops up, telling us that we are trying to reference a variable before assigning it.
If we want Python to use a global variable, we have to explicitedly tell it to using the keyword global. Modify your code to this and then try to predict what will get printed out before running it, to see if your prediction was correct.
def scope():
global message
print (message)
message = "Lily Bobtail"
print (message)
message = "Peter Rabbit"
scope()
print (message)
So now, we set the variable to hold 'Peter Rabbit'. We then called the function and told the function to use the global variable 'message'. It doesn't matter that later on in the function, we change the value that this variable holds - it doesn't ever become a local variable in the function now because we told the function it will always be global at the start of the function, by using the keyword global. So now, 'Peter Rabbit' gets printed, then the global variable is changed to 'Lily Bobtail'. Then we print out the variable again, which prints 'Lily Bobtail' and exit the function. The last line of the program says print out the variable again, which of course is global and still holds 'Lily Bobtail' now.