如何理解Python中的 if __name__ == '__main__'
’
用了一段时间Python,总是见到这个语句,在Pycharm中会有一个小小的绿色箭头可以直接点击执行,但是一直不知道具体是什么意思:
今天又遇到了,于是去网上参考了几个优秀的回答,这里mark一下。
程序入口
对于很多编程语言来说,程序必须要有一个入口,比如C/C++是int main()
,JAVA是public static void main(String args[])
,也就是说程序运行时会先从main
函数开始。而Python则不同,它数据脚本语言,和Matlab比较像,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行,就是从脚本第一行开始运行,没有统一的入口。
Python源码文件有两种使用方式:直接运行或者作为模块import
。而不管哪种运行方式,py文件的代码都会被运行,而在实际情况中,有一部分代码我们是不希望被运行的。
举个栗子说明一下,假设我们新建了一个helloworld.py
文件,里面有一个sayHello()
:函数输出字符串,最后运行sayHello()
相当于做了一篇检查,看看是否正常输出。
def sayHello():
print('Hello World!')
sayHello()
执行helloworld.py
后会输出“Hello World”字样。现在如果我们有另一个demo.py
文件,该文件需要用到sayHello()
这个函数,于是我们将helloworld.py
导入到demo.py
中:
import helloworld
print('I don\'t want to say hello')
最后程序demo.py
的执行结果会是
# Hello World!
# I don't want to say hello
可以看到,demo.py
中的sayHello()
函数也被执行了,实际上我们是不希望它被运行的,这时if __name__ == '__main__
就派上用场了。现在我们将helloworld.py
改写成:
def sayHello():
print('Hello World!')
if __name__ == '__main__':
sayHello()
else:
print('My name is %s' % __name__)
现在如果直接运行helloworld.py
输出依然是“Hello World”,此时再运行demo.py
的话,输出就变成了:
# My name is helloworld
# I don't want to say hello
if __name__ == '__main__'
就相当于是 Python 模拟的程序入口。Python 本身并没有规定这么写,这只是一种编码习惯。由于模块之间相互引用,不同模块可能都有这样的定义,而入口程序只能有一个。到底哪个入口程序被选中,这取决于 __name__
的值。
模块变量
那么上面__name__
到底是个啥呢?原来每个Python模块(即.py文件)都包含一组內建的模块变量,当加载该模块的时候,Python虚拟机会自动为这些变量赋值。常见的有下面几种变量:
__name__ //打印出完整的 命名空间
__package__ //包
__doc__ //注释
__file__ //文件路径
继续回到上面的问题,当helloworld.py
文件被直接运行的时候,Python虚拟机会给该helloworld模块的__name__
变量自动赋值为__main__
,而当helloworld模块import到其它模块中时,则给__name__
变量赋值为模块名,即helloworld
。到这里应该就很清楚了,为啥加了if __name__ == '__main__'
后就能控制代码块在导入的时候不被执行。
所以,if __name__ == '__main__'
我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。