简单而言,if __name__ == ‘__main__’ 我们简单的理解就是: 如果模块是被直接运行的,则if __name__ == '__main__'
下的代码块被运行;如果模块是被导入的,则if __name__ == '__main__'
下的代码块不被运行。
下面是详细阐述:
1 程序入口
对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面向对象的编程语言 Java等。C 和 C++ 都需要有一个 main 函数来作为程序的入口,也就是程序的运行会从 main 函数开始。
Python 则有不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
一个 Python 源码文件除了可以被直接运行外,还可以作为模块(也就是库)被导入。不管是导入还是直接运行,最顶层的代码都会被运行。而实际上在导入的时候,有一部分代码我们是不希望被运行的。
下面是一个例子,文件名为naruto.py,内容为:
在文件里边定义了一个常量,然后又写了一个 main 函数来输出这个常量,最后运行 main 函数就相当于对定义做一遍人工检查,看看值设置的都对不对。试一试吧:直接执行该文件(naruto.py),输出:
接下来,这里有一个sasuke.py,功能是计算圆面积,该文件里边需要用到 naruto.py 文件中的pi变量,那么我们从naruto.py 中把pi变量导入到sasuke.py 中,下面是sasuke.py的内容:
运行sasuke.py的输出结果如下:
可以看到,naruto中的 main 函数也被运行了,实际上我们是不希望它被运行,提供 main 也只是为了对常量定义进行下测试。这时,if __name__ == '__main__'
就派上了用场。把 naruto.py 改成下面的代码:
将naruto.py保存后,运行sasuke.py,输出如下:
再运行naruto.py,输出如下:
这样才是我们想要的效果。
1.1 解释
if __name__ == '__main__'
相当于是 Python 模拟的程序入口。由于模块之间相互引用,不同模块可能都有这样的定义,而入口程序只能有一个。到底哪个入口程序被选中,这取决于 name 的值。
2 __name__
__name__
是内置变量,用于表示当前模块的名字,同时还能反映一个包的结构。举个例子,假设有如下一个包:
上面的意思是说,a文件夹下有b文件夹和__init__.py。又有b文件夹下有c.py和__init__.py。
我们先在一个目录(我这里是D盘,以后都是这样,不重复说了)里新建一个文件夹命名为a,然后打开文件夹a,新建文件夹命名为b,在文件夹a中再新建一个文件命名为__init__.py
。再打开文件夹b,在文件夹b中新建两个文件__init__.py
与c.py
。这三个.py文件内容都是:
然后在命令行执行下面的命令:
结果为:
在这里,python -c
支持执行单行命令/脚本,如:
输出:
注意:要用双引号将命令包起来,import要以;
结尾,命令用[]括起来,多行命令用多个[],如;
输出:
由此可见,__name__
可以清晰的反映一个模块在包中的层次。
如果一个模块被直接运行,则其没有包结构,其 __name__
值为 __main__
。
例如,在上例中,我们直接运行 c.py 文件(python a/b/c.py),输出结果如下:
所以,if name == ‘main’ 我们简单的理解就是: 如果模块是被直接运行的,则if __name__ == '__main__'
下的代码块被运行;如果模块是被导入的,则if __name__ == '__main__'
下的代码块不被运行。
到这里就讨论完了if __name__ == '__main__'
的作用。
3 参考文献
python -c 执行单行命令/脚本,有点意思
Python 中的 if name == ‘main’ 该如何理解