Python __name__ variable and Usage

Sept. 1, 2020

Introduction: What is the Python __name__ variable and when to use it in your code.


You probably have seen this block of code many times before:

if __name__ == "__main__":

....<code>

You probably also know the purpose of this code, it means the code below if __name__ == "__main__" statement is executed when we execute the file as a standalone file. But why do we need this extra block?

Consider this script:

(venv) echou@network-dev-2:/tmp$ cat script1.py

#!/usr/bin/env python

def router_name(name):

....print(f'Hello {name}!')

if __name__ == '__main__':

....router_name('LAX-R1')

And this script:

(venv) echou@network-dev-2:/tmp$ cat script2.py

#!/usr/bin/env python

def router_name(name):

....print(f'Hello {name}!')

router_name('LAX-R1')

The end results are exactly the same:

(venv) echou@network-dev-2:/tmp$ python3 script1.py

Hello LAX-R1!

(venv) echou@network-dev-2:/tmp$ python3 script2.py

Hello LAX-R1!

So why do we even bother to put that into an if block?

The Special __name__ Variable

The answer is in the special __name__ variable and the scope that it executes. According to the Python documentation, https://docs.python.org/3/library/__main__.html, the module can discover whether or not it is running as a standalone script (in the __main__ scope) or as an imported module by checking this variable.

pyhton_main_scope.png

Here is another documentation link that explains the same concept, https://docs.python.org/3/tutorial/modules.html#executing-modules-as-scripts:

python_name_main_scope.png

I understand it might not be intuitive to think of the Python code as a re-usable module, especially if someone is just starting to learn Python. If we start to think of the script as a module that can be executed both by itself or be imported by other Python scripts, this would make a lot more sense.

Let's look at another follow-up example.

Separation of Command-Line Execution vs. Import

Consider the following two scripts that do nothing but import script1.py and script2.py, respectively (you omit the .py extension when doing imports):

(venv) echou@network-dev-2:/tmp$ cat script3.py

#!/usr/bin/env python

import script1

(venv) echou@network-dev-2:/tmp$ cat script4.py

#!/usr/bin/env python

import script2

When we execute them, these are the results:

(venv) echou@network-dev-2:/tmp$ python script3.py

(venv) echou@network-dev-2:/tmp$ python script4.py

Hello LAX-R1!

The result of script4.py is probably NOT what you wanted, right? The function was invoked automatically when we import the non-if block (script4.py) whereas the function will be available when imported but ONLY execute when it is invoked by itself. There are some cases where you'd like some code to always execute when it is imported, but most of the time we'd like to keep the functions we import silently until we need to use them.

We can also test this out in an interactive prompt:

>>> import script1

>>> import script2

Hello LAX-R1!

>>> script1.router_name('NYC-R1')

Hello NYC-R1!

>>> script2.router_name('NYC-R1')

Hello NYC-R1!

Conclusion

As a rule of thumb, think of our scripts as Python modules that is expected to be executed both as a standalone script as well as an imported module by other programs. Put the code we'd like to run in the if __name__ == "__main__" block when it is run as a standalone script.

I hope this post is useful to you, let me know what you think and leave me a comment below.


Happy coding!

Eric

Return to blog