Python 中的 if __name__ == 'main' 的作用和原理
一句话,秒懂
__name__ 是当前模块名,当模块被直接运行时模块名为 __main__ 。这句话的意思就是,当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行。
简而言之就是:__name__ 是当前模块名,当模块被直接运行时模块名为 __main__ 。当模块被直接运行时,代码将被运行,当模块是被导入时,代码不被运行。
由于每个Python模块(Python文件)都包含内置的变量__name__,当运行模块被执行的时候,__name__等于文件名(包含了后缀.py)。如果import到其他模块中,则__name__等于模块名称(不包含后缀.py)。而“__main__”等于当前执行文件的名称(包含了后缀.py)。所以当模块被直接执行时,__name__ == '__main__'结果为真;而当模块被import到其他模块中时,__name__ == '__main__'结果为假,就是不调用对应的方法。
原文链接:https://blog.csdn.net/wrh_csdn/article/details/80534654#:~:text=%E7%99%BB%E5%BD%95%2F%E6%B3%A8%E5%86%8C-,%E7%A7%92%E6%87%82Python%E7%BC%96%E7%A8%8B%E4%B8%AD%E7%9A%84if%20__name__,main'%20%E7%9A%84%E4%BD%9C%E7%94%A8%E5%92%8C%E5%8E%9F%E7%90%86&text=__name__%20%E6%98%AF%E5%BD%93%E5%89%8D,%E4%BB%A3%E7%A0%81%E5%9D%97%E4%B8%8D%E8%A2%AB%E8%BF%90%E8%A1%8C%E3%80%82
实例:
本回答(包括z示例代码代码)节选和总结自Huoty的博客:
Python 中的 if __name__ == '__main__' 该如何理解
对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面向对象的编程语言 Java,C# 等。如果你接触过这些语言,对于程序入口这个概念应该很好理解,C 和 C++ 都需要有一个 main 函数来作为程序的入口,也就是程序的运行会从 main 函数开始。同样,Java 和 C# 必须要有一个包含 Main 方法的主类来作为程序入口。
而 Python 则有不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
一段好的示例代码胜过一切
这里有俩个程序
const.py用来定义常数PI
area.py需要PI这个常数来计算圆的面积
const.py 代码如下:
PI = 3.14
def main():
print "PI:", PI
main()
当运行python const.py,输出
PI: 3.14
area.py (导入PI的值来计算圆面积)代码如下
from const import PI
def calc_round_area(radius):
return PI * (radius ** 2)
def main():
print "round area: ", calc_round_area(2)
main()
当运行python area.py,因为导入了const,输出
PI: 3.14
round area: 12.56
可以看到
const.py里面的main()也被执行了
但这是我们所不希望的
怎么办?
只需在const.py中加入一句:
PI = 3.14
def main():
print "PI:", PI
if __name__ == "__main__":
main()
_name_代表当前模块的名字
当我们再次运行“python area.py”时
对于const.py来说
_name_不再是_main_
因此其中的main()不再被执行
最终得到我们想要的输出
round area: 12.56
以上示例代码及注释部分取自博文(非常好的总结文章,还详细解释了_name_):
__main__.py 文件与 python -m
Python 的 -m
参数用于将一个模块或者包作为一个脚本运行,而 __main__.py
文件则相当于是一个包的”入口程序“。
首先我们需要来看看 python xxx.py
与 python -m xxx.py
的区别。两种运行 Python 程序的方式的不同点在于,一种是直接运行,一种是当做模块来运行。
先来看一个简单的例子,假设有一个 Python 文件 run.py,其内容如下:
import sys
print sys.path
我们用直接运行的方式启动(python run.py),输出结果(为了说明问题,输出结果只截取了重要部分,下同):
['/home/huoty/aboutme/pythonstudy/main', ...]
然后以模块的方式运行(python -m run.py):
['', ...]
/usr/bin/python: No module named run.py
由于输出结果只列出了关键的部分,应该很容易看出他们之间的差异。直接运行是把 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
.
这个例子并不能明显的说明问题。接着我们来看看 __main__.py
的作用。
仍然先看例子,有如下一个包:
package
├── __init__.py
└── __main__.py
- __init__.py
import sys
print "__init__"
print sys.path
- __main__.py
import sys
print "__main__"
print sys.path
用 python -m package
运行结果:
__init__
['', ...]
__main__
['', ...]
用 python package
运行结果:
__main__
['package', ...]
然后我们来总结一下:
- 1、 加上 -m 参数时会把当前工作目录添加到 sys.path 中,而不加时则会把脚本所在目录添加到 sys.path 中。
- 2、 加上 -m 参数时 Python 会先将模块或者包导入,然后再执行
- 3、 __main__.py 文件是一个包或者目录的入口程序。不管是用
python package
还是用python -m package
运行时,__main__.py 文件总是被执行。
后序
我试图使用长篇大论来阐述,在 Python 中如何理解 if __name__ == '__main__'
这个问题,不知道我有没有描述得足够的明白。Python 的确是简单的,优雅的,但也有很多问题是不太容易理解的,例如很多高级的特性,像元类、生成器表达式、描述符、协程等。Python 并没有在太多的地方规定要如何如何,很多的用法只是惯用法,例如 self 和本文讨论的内容。这些用法或是为了让代码看起来更优雅,或是前人的经验。使用 Python 是有无限可能的,你可以写出很多简洁优雅的代码。
原文链接:https://blog.konghy.cn/2017/04/24/python-entry-program/
如果这篇文章帮助到了你,你可以请作者喝一杯咖啡