__name__ == "__main__"
In Python, a script is simply a file with Python code inside and a .py
file extension. You can execute scripts as standalone files from the command line with the python3
command.
In Python, a module is a code file, like a script, that you import into another code file. You can import files into other files in your project or you can import files into a Python interactive shell session. The term “module” is used to describe reusable code.
Let’s take the following code as an example:
stocks.py
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
We can run this as a script:
python3 stocks.py
But nothing happens. It doesn’t throw any errors, so it seems to have worked. But it also doesn’t produce any output. It only defines objects. Let’s modify the code so it produces some output so we can see if our code actually works:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
When we run this as a script again we should see some output:
We are in the middle of a bear market. Woo wee!
The stock price for Monday is $100.
The problem is that if we want to use this code as an imported module, then we will also see the output:
Start an interactive Python shell:
python3
And import the module:
>>> import stocks
We are in the middle of a bear market. Woo wee!
The stock price for Monday is $100.
That is not typically the desired behavior. When you import a module, you probably don’t want to see output from the imported module.
Often when we are developing code, we want to run a file as a script that produces output so we can test the code as we are developing it. But once the code has been developed and tested, it would be nice to keep our test code around and turn off the output so the file can be imported and used in our project. We just don’t want the output from our tests showing up once the module has been imported. Well, Python let’s you do exactly that with the special dunder (double underscore) variable __name__
.
Every Python file has a __name__
variable. When a Python file is run as a script, then the __name__
variable will be set to "__main__"
because the standalone script is the “main” program that is running. On the other hand, if the file is imported as a module, then __name__
will be assigned the name of the file itself (which is typically the file name without the .py
extension). For example, if our script.py
file were imported as a module, then the __name__
variable for script.py
would be "script"
.
This mechanism enables Python code to discern whether it’s being run as the main program (i.e. executed directly as a script) or imported as a module. What this means in practice is that you can conditionally run blocks of code based on the value of the __name__
variable. For example, update the code in stocks.py
to match this:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
Now run the file as a script:
python3 stocks.py
__name__ == "__main__"
We are in the middle of a bear market. Woo wee!
The stock price for Monday is $100.
And run it as an imported module:
python3
>>> import stocks
__name__ == "stocks"
Notice how the output under the if
statement only runs when __name__ == "__main__"
. How cool is that!
You can even pass arguments to the function test various scenarios. Update the code as in the following example. Notice that the print()
function above the if
statement has been removed and the code block under the if
statement now captures arguments that are passed through the command line.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
Run the file as a script, referencing the function name and passing an argument to the function:
python3 stocks.py get_stock_price "Friday"
The stock price for Friday is $500.
Run it as an imported module, calling the function and passing the function an argument:
python3
>>> from stocks import get_stock_price
>>> get_stock_price("Friday")
The stock price for Friday is $500.
Now you can use the __name__
variable to your advantage while developing Python code.