程序入口,即程序运行的起点,也就是我们常说的main()函数。
比如 C,C++,以及完全面向对象的编程语言 Java,C# 等。C 和 C++ 都需要有一个 main 函数来作为程序的入口。Java 和 C# 必须要有一个包含 Main 方法的主类来作为程序入口。
而 Python 则有所不同,它属于 脚本语言,不像 编译型语言那样先将程序编译成二进制再运行,而是 动态的逐行解释运行,也就是 从脚本第一行开始运行,没有统一的入口,也就是所谓的“main()”方法。在.py文件中,除了def后定义函数外的代码都会被认为是“main”方法中的内容从上而下执行。
这样就会带来一个问题。
一个 Python 源码文件除了可以被直接运行外,还可以作为模块(也就是库)被导入。
不管是导入还是直接运行,最顶层的代码都会被运行(Python 用缩进来区分代码层次)。而实际上 在导入的时候,有一部分代码我们是不希望被运行的(我们只想使用模块提供的函数,不想运行模块自身的测试函数、检查函数)。
举一个例子来说明
假设我们有一个 const.py 文件,内容如下:
PI = 3.14
def main():
print "PI:", PI
main()
我们在这个文件里边定义了一些常量,然后又写了一个 main 函数来输出定义的常量,最后运行 main 函数就相当于对定义做一遍人工检查,看看值设置的都对不对。然后我们直接执行该文件(python const.py),输出:
PI: 3.14
现在,我们有一个 area.py 文件,用于计算圆的面积,该文件里边需要用到 const.py 文件中的 PI 变量,那么我们从 const.py 中把 PI 变量导入到 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()
运行 area.py,输出结果:
PI: 3.14
round area: 12.56
可以看到,const 中的 main 函数也被运行了,实际上我们是不希望它被运行,提供 main 也只是为了对常量定义进行下测试。
这时 if __name__ == '__main__'
就派上用场了
if __name__ == '__main__'
if __name__ == '__main__'
相当于是 Python (人为)模拟的程序入口。Python 本身没有规定必须这么写,只是一种编码习惯。 由于模块之间相互引用,不同模块可能都有相关的定义,而入口程序只能有一个。 到底哪个入口程序被选中,这取决于 name 的值。
__name__
__name__
是内置变量,用于 表示当前模块的名字,同时还能 反映一个包的结构。来举个例子,假设有如下一个包:
a
├── b
│ ├── c.py
│ └── __init__.py
└── __init__.py
目录中所有 py 文件的内容都为:
print __name__
我们执行 python -c “import a.b.c”,输出结果:
a
a.b
a.b.c
由此可见,__name__
可以清晰的反映一个模块在包中的层次。其实,所谓模块名就是 import 时需要用到的名字,例如:
import tornado
import tornado.web
这里的 tornado 和 tornado.web 就被称为模块的模块名。
如果一个模块被直接运行,则其没有包结构,其 __name__
值为 __main__
。例如在上例中,我们直接运行 c.py 文件(python a/b/c.py),输出结果如下:
__main__
简单来说,if __name__ == '__main__'
的用法就是:当.py文件被直接运行时,if __name__ == '__main__'
之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'
之下的代码块不被运行。
参考:http://blog.konghy.cn/2017/04/24/python-entry-program/