You may have heard about "names" in Python. They're "sort-of variables", but not quite…
Let's look at a different way of looking at names in Python
We'll use boxes, books, rooms, and doors as props to understand names and Python programs in general
Let's start with a blank Python script. It's a `.py` file but there's no code in it for now
I'd like you to image a medium-sized room. The room is empty except for a set of shelves on one of the walls
There's also a small red booklet on the bottom shelf called "built-in"
I will personify the program and call it Monty (why not!). You can picture Monty to be anything you like: a person, an elf, a robot, anything else…
Let's add some code:
import random
Monty (that's the program, remember) leaves this room and goes to a large library with thousands of books. He finds one named `random` and brings it back to the room
The `random` book is now on one of the shelves in this room. The book is clearly labelled with the name `random` on the spine and the front of the book
Let's add another couple of lines of code:
author = "Stephen"
favourite_number = random.randint(1, 10)
Monty fetches a couple of empty cardboard boxes…
He places the string `"Stephen"` in one of the boxes. Monty also sticks a label to the outside of this box and writes "author" on this label
He places the box on one of the shelves, with the label with "author" written on it clearly visible
When it comes to the second line of code, Monty looks at `random.randint(1, 10)` first
The first name he reads is "random". Monty looks around the room for this label and finds it on the spine of a book on one of the shelves
He brings this book down from the shelf. He knows he needs to look for the name "randint" inside this book. Monty know this because of the dot in between "random" and "randint"
I'll fast-forward the next bit as we've not talked about functions yet and `randint()` is a function. So let's fast-forward to the point when Monty has a number in his hand that comes from `random.randint()`
Let's say he's got the number 7
Monty places this number, 7, into the second cardboard box, puts a label on the box and writes "favourite_number" on the label. He places the box on the shelf next to the other box that's already there
From now on, whenever Monty reads `author` or `favourite_number` in the code, he'll look for this label in the room and he'll find a box with that label. Monty will fetch whatever is in that box
Let's define a function
def show_favourite_number(person, number):
print(f"{person}'s favourite number is {number}")
Did I already say Monty has some magical powers? I've said it now. He can quickly build a new room adjacent to the current one
So now we have the Main Room and the Function Room
There's a door connecting the two rooms
Monty puts a label on the door which leads from the Main Room to the Function Room and writes "show_favourite_number" on this label on the door
The label is visible from the Main Room
The Function Room also has some shelves on one of the walls. In many ways, it looks similar to the Main Room. There's even another copy of the red "built-in" booklet
But, there's also a table as soon as you enter the Function Room. The table has two cardboard boxes on it
The boxes on this table at the entrance of the Function Room are empty. But these boxes already have labels on them. One is labelled "person" and the other "number"
These are the parameter names used in the function definition
So, when you define a function, you have two boxes, already labelled, ready to store some content inside them. But they're still empty for now
Let's call the function and see what Monty does when he reads the function call
This function call is in the main program. Therefore, Monty is in the Main Room when he reads this:
show_favourite_number(author, favourite_number)
He reads the first name "show_favourite_number". He looks around the room to find this label. None of the books are labelled "show_favourite_number" and none of the boxes have that label, either
However, he finds the label on the door leading to another room. Monty knows this is a function as doors lead to Function Rooms. The parentheses after the function name tell him he needs to go through this door to the Function Room
But before he makes his way to the door with `show_favourite_number` on it, he reads the names in the parentheses of the function call, "author" and "favourite_number"
You can see what's happening here. He looks around the room and finds two boxes with those labels. He fetches both boxes and gets their contents
He doesn't take the boxes with him but he takes whatever is inside them, and he goes through the Function Room door…
As soon as he enters the Function Room, he sees the table with the two empty boxes. He places the first item he's holding in the box labelled `person` and the second item in the box labelled `number`
Monty takes these boxes and puts them on the shelves in the Function Room
He's now ready to do whatever is required of him in this Room before returning to the Main Room
He reads the name "print". He looks around the room for a label with "print" on it. He doesn't find one
Remember the red "built-in" booklet? If Monty doesn't find a label he's looking for, he'll look inside this red booklet for the name
He finds "print" in this booklet
The booklet gives Monty directions to find another Function Room. This is not adjacent to the room he's in, but he can leave the small complex of two rooms and follow the directions to find the Function Room with `print` on the door elsewhere in "Python City"
`print` is a function like `show_favourite_number`. It's only its location in Python City that's different
Before Monty goes for the stroll to the `print` Function Room, he fetches the contents of the boxes `person` and `number`. These boxes are on the shelves of the `show_favourite_number` Function Room
Once Monty performs all his tasks in the `print` room, he returns to the `show_favourite_number` room and there's nothing left to do here either
He returns to the Main Room empty handed. Recall that the function returns `None` since it doesn't have an explicit `return` statement.
Let's change both the function definition and the function call:
def show_favourite_number(person, number):
output = f"{person}'s favourite number is {number}"
return output
result = show_favourite_number(author, favourite_number)
This time, when Monty goes to the `show_favourite_number` Function Room, he uses the contents of the `person` and `number` boxes in the Function Room to create a string (an f-string in this case)
He places this string in a new cardboard box and labels this box "output". He puts this box on one of the shelves in the Function Room
On the next line, Monty sees a `return` statement. He knows his job is done in this Function Room and he needs to return to the Main Room where he came from originally
But, before he leaves, he reads what's after the `return` keyword. He reads the name "output"
He gets the box labelled "output" and fetches its contents. It contains a string. He takes this string back to the Main Room
He doesn't take the whole box labelled "output". He only takes its contents
Back in the Main Room, there is no "output" label anywhere to be seen
The line in the main program calling the function also has an assignment. So Monty fetches another empty cardboard box, places the string he just brought back with him form the Function Room in this box and labels the box "result"
This box goes in a shelf in the Main Room
Remember when we fast-forwarded what happens when Monty reads the following:
favourite_number = random.randint(1, 10)
The "randint" entry in the "random" book also gives directions for Monty to be able to find the `randint` Function Room in Python City
So Monty leaves the Main Room, goes to the "randint" room, and then comes back to the Main Room with the integer he got form the "randint" Function Room
This analogy gives us a way of picturing scope in a simplified way. When Monty is in the Main Room, he's got access to any label in that room or in the built-in booklet but not in the Function Room
When a function is called and Monty goes to the Function Room, he's got access to labels in the Function Room and, because he doesn't shut the door leading back to the Main Room, he also still has access to everything in the Main Room
I'll finish off with my usual analogy-caveat or disclaimer: Analogies are not a perfect representation of what's happening and they'll break down if you push too far
But hopefully, this vision of Monty moving from one room to another, storing data in boxes, and labelling everything with Python names, will help understand what's going on in a Python program