How to understand if __name__ == '__main__' in Python

Program entry

For many programming languages, programs must have an entry, such as C, C++, and fully object-oriented programming languages ​​Java, C#, etc. If you have been exposed to these languages, you should have a good understanding of the concept of program entry. Both C and C++ need to have a main function as the entry of the program, that is, the running of the program will start from the main function. Likewise, Java and C# must have a main class with a Main method as the entry point for the program.

Python is different. It belongs to a scripting language. Unlike compiled languages, the program is first compiled into binary and then run. Instead, it is dynamically interpreted line by line. That is, it runs from the first line of the script, and there is no unified entry.

In addition to being directly executable, a Python source file can also be imported as a module (ie, a library). Regardless of whether it is imported or run directly, the top-level code will be executed (Python uses indentation to distinguish code levels). In fact, when importing, there is a part of the code that we do not want to be run.

To illustrate with an example, suppose we have a const.py file with the following content:

PI = 3.14

def main():
    print "PI:", PI

main()

 We define some constants in this file, and then write a main function to output the defined constants. Finally, running the main function is equivalent to manually checking the definitions to see if the values ​​are set correctly. Then we directly execute the file (python const.py), output:

PI: 3.14

 Now, we have an area.py file for calculating the area of ​​a circle, which needs to use the PI variable in the const.py file, then we import the PI variable from const.py into area.py:

from const import PI

def calc_round_area(radius):
    return PI * (radius ** 2)

def main():
    print "round area: ", calc_round_area(2)

main()

 Run area.py and output the result:

PI: 3.14
round area:  12.56

 It can be seen that the main function in const is also run. In fact, we do not want it to be run. Main is provided only to test the constant definition. That's when if __name__ == '__main__' it came in handy. Change const.py to:

PI = 3.14

def main():
    print "PI:", PI

if __name__ == "__main__":
    main()

 Then run area.py again, the output is as follows:

round area:  12.56

 Run const.py again, the output is as follows:

PI: 3.14

This is the effect we want.

if __name__ == '__main__' It is equivalent to the program entry of Python  simulation . Python itself does not stipulate this, it is just a coding habit. Due to the mutual reference between modules, different modules may have such definitions, and the entry program can only have one. Exactly which entry program is selected depends on  __name__ the value of .

__name__

__name__ Is a built-in variable, used to represent the name of the current module, and also reflects the structure of a package. As an example, suppose you have the following package:

a
├── b
│   ├── c.py
│   └── __init__.py
└── __init__.py

 The contents of all py files in the directory are:

print __name__

 We execute  python -c "import a.b.c"and output the result:

a
a.b
a.b.c

It can be seen that __name__ the level of a module in the package can be clearly reflected. In fact, the so-called module name is the name that needs to be used when importing, for example: 

import tornado
import tornado.web

Here tornado and tornado.web are called the module name of the module.

If a module is run directly, it has no package structure and its  __name__ value is  __main__. For example, in the above example, we directly run the c.py file (python a/b/c.py), and the output is as follows:

__main__

Therefore, if __name__ == '__main__' our simple understanding is:  if the module is directly executed, the code block is executed, and if the module is imported, the code block is not executed .

In fact, this problem can also derive some other knowledge points, such as  __main__.py files and Python  -m parameters.

__main__.py file with python -m

Python's  -m parameters are used to run a module or package as a script, and a  __main__.py file is equivalent to a package's "entry program".

First we need to look at  python xxx.py the  python -m xxx.py difference with . The difference between the two ways of running Python programs is that one is run directly, and the other is run as a module.

Let's look at a simple example first. Suppose there is a Python file run.py with the following contents:

import sys
print sys.path

 We start it by running it directly (python run.py), and output the result (in order to illustrate the problem, only the important part of the output result is intercepted, the same below):

['/home/huoty/aboutme/pythonstudy/main', ...]

 Then run it as a module (python -m run.py):

['', ...]
/usr/bin/python: No module named run.py

 Since only the critical parts are listed in the output, it should be easy to see the differences. Direct operation is to put the directory where the run.py file is located in the sys.path attribute. Running in module mode puts the directory you entered the command into (that is, the current working path) into the sys.path property. Another difference to running as a module is an extra line  No module named run.py of errors. In fact, when running in module mode, Python first executes the import of run.py, so it  print sys.path is successfully executed, and then Python tries to run the run.py module. However, there is no run.py module in the path variable, so an error is reported. And the correct way to run it should be  python -m run.

This example does not clearly illustrate the problem. Then let's look at  __main__.py the effect.

Still looking at the example first, there is the following package:

package
├── __init__.py
└── __main__.py
  • __init__.py
import sys
print "__init__"
print sys.path
  • __main__.py
import sys
print "__main__"
print sys.path

 Use the  python -m package result of running: 

__init__
['', ...]
__main__
['', ...]

Use the  python package result of running:

__main__
['package', ...]

 Then let's summarize:

  • 1.  When the -m parameter is added, the current working directory will be added to sys.path, and if it is not added, the directory where the script is located will be added to sys.path .
  • 2.  When adding the -m parameter, Python will first import the module or package, and then execute the
  • 3.  The __main__.py file is the entry program of a package or directory.  The __main__.py file is always executed regardless of  python package whether  the runtime is used.python -m package

post-order

I'm trying to use a tirade to explain how to understand  if __name__ == '__main__' this problem in Python, I don't know if I describe it well enough. Python is indeed simple and elegant, but there are also many problems that are not easy to understand, such as many advanced features, such as metaclasses, generator expressions, descriptors, coroutines, etc. Python doesn't specify how to do it in many places, and many uses are just idioms, such as self and what this article discusses. These usages are either to make the code look more elegant, or previous experience. The possibilities are endless with Python, and you can write a lot of clean and elegant code.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325387648&siteId=291194637