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

1. Abstract (from Locutus )

Popular understanding __name__ == '__main__': if your name is Xiaoming.py, in the eyes of friends, you are Xiaoming (__name__ == '小明'); in your own eyes, you are yourself (__name__ == '__main__').

if __name__ == '__main__'It means: when the .py file is run directly, if __name__ == '__main__'the code block below will be run; when the .py file is imported as a module, if __name__ == '__main__'the code block below will not be run.


2. 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 a main function as the entry of the program, that is, the running of the program will start from the main function. Similarly, Java, C# must have a main class that contains the Main method as the program entry.

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 run directly, a Python source file (.py) can also be used as a module (that is, a library) and imported by other .py files. Whether it is run directly or imported, the top-level code of the .py file will be run (Python uses indentation to distinguish code levels), and when a .py file is imported as a module, we may not want part of the code to be run.

2.1 A .py file is referenced by other .py files

Suppose we have a const.py file with the following content:

PI = 3.14

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

main()

# 运行结果:PI: 3.14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Now, let's write an area.py file for calculating the area of ​​a circle. The area.py file needs to use the PI variable in the const.py file. From const.py, we import the PI variable 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()

'''
运行结果:
PI: 3.14
round area:  12.56
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.2 Modify const.py and addif __name__ == "__main__"

We see that the main function in const.py is also run, in fact we don't want it to be run because the main function provided by const.py is only for testing constant definitions. At this time if __name__ == '__main__', it comes in handy. We change const.py and add if __name__ == "__main__":

PI = 3.14

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

if __name__ == "__main__":
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Running const.py, the output is as follows:

PI: 3.14
  • 1

Running area.py, the output is as follows:

round area:  12.56
  • 1

As above, we can see if __name__ == '__main__'the program entry equivalent to Python simulation. Python itself does not stipulate this, it is just a coding habit. Since modules refer to each other, different modules may have such definitions, and there is only one program entry. Exactly which program entry is selected depends on __name__the value of . 

3. __name__

3.1  __name__Reflecting the structure of a package

__name__are built-in variables that can be used to reflect the structure of a package. Suppose we have a package a, the structure of the package is as follows:

a
├── b
│   ├── c.py
│   └── __init__.py
└── __init__.py
  • 1
  • 2
  • 3
  • 4
  • 5

In package a, c.py,__init__.py,__init__.pythe contents of the files are:

print(__name__)
  • 1

When a .py file (module) is imported by another .py file (module), we execute on the command line

python -c "import a.b.c"
  • 1

Output result:

a
a.b
a.b.c
  • 1
  • 2
  • 3

It can be seen that __name__the level of a module in the package can be clearly reflected.

3.2  __name__Indicates the name of the current module

__name__is a built-in variable that can be used to represent the name of the current module. We run a .py file (module) directly

python a/b/c.py
  • 1

Output result:

__main__
  • 1

From this we know that if a .py file (module) is run directly, it has no package structure, and its __name__value __main__is the module name __main__.

So, if __name__ == '__main__'the meaning is: when the .py file is run directly, if __name__ == '__main__'the code block below will be run; when the .py file is imported as a module, if __name__ == '__main__'the code block below will not be run.


4.  __main__.pyDocument andpython -m

Python's -m parameter is used to run a module or package as a script, and the __main__.pyfile is equivalent to the "entry program" of a package.

4.1 运行Python程序的两种方式

  • python xxx.py,直接运行xxx.py文件
  • python -m xxx.py,把xxx.py当做模块运行

假设我们有一个文件run.py,内容如下:

import sys

print(sys.path)
  • 1
  • 2
  • 3

我们用直接运行的方式启动

python run.py
  • 1

输出结果(为了说明问题,输出结果只截取了重要部分,下同):

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

然后以模块的方式运行:

python -m run.py
  • 1

输出内容

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

由于输出结果只列出了关键的部分,应该很容易看出他们之间的差异:

  • 直接运行方式是把run.py文件所在的目录放到了sys.path属性中

  • 以模块方式运行是把你输入命令的目录(也就是当前工作路径),放到了 sys.path 属性中。

以模块方式运行还有一个不同的地方:多出了一行No module named run.py的错误。实际上以模块方式运行时,Python先对run.py执行一遍 import,所以print(sys.path)被成功执行,然后Python才尝试运行run.py模块,但是在path变量中并没有run.py这个模块,所以报错。正确的运行方式,应该是python -m run

4.2 __main__.py的作用

仍然先看例子,假设我们有如下一个包package:

package
├── __init__.py
└── __main__.py
  • 1
  • 2
  • 3

其中,文件__init__.py的内容

import sys

print("__init__")
print(sys.path)
  • 1
  • 2
  • 3
  • 4

其中,文件__main__.py的内容

import sys

print("__main__")
print(sys.path)
  • 1
  • 2
  • 3
  • 4

接下来,我们运行这个package,使用python -m package运行,输出结果:

__init__
['', ...]

__main__
['', ...]
  • 1
  • 2
  • 3
  • 4
  • 5

使用python package运行,输出结果:

__main__
['package', ...]
  • 1
  • 2

总结一下

  • 当加上-m参数时,Python会把当前工作目录添加到sys.path中;而不加-m时,Python则会把脚本所在目录添加到sys.path中。

  • 当加上-m参数时,Python会先将模块或者包导入,然后再执行。

  • __main__.py文件是一个包或者目录的入口程序。不管是用python package还是用python -m package运行,__main__.py文件总是被执行。 

Guess you like

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