Python中的if __name__ == '__main__'(转载)

这里只是作个简单的笔记,更多精彩可阅读原作者的博客:

https://blog.csdn.net/yjk13703623757/article/details/77918633

首先感谢原作者精彩的总结和分析~~~

1前言

        以前没有详解过if __name__ =='__main__'的作用,只知道当执行.py文件的时候,需要在末尾添加这行代码作为执行.py程序的入口:

          

if __name__ == '__main__':
     main()

          

if __name__ =='__main__'的意思是:当.py文件被直接运行的时候,if __name__ =='__main__':下方的代码将被执行;当.py文件以模块形式被导入时,if __name__ =='__main__'下代码不被执行

2 程序入口

         python属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本的第一行开始运行,没有统一的入口

           一个Python源码文件(.py)除了可以被直接运行外,还可以作为模块(库),被其他.py文件导入。不管是直接运行还是被导入,.py文件的最顶层代码都会被运行(python用缩进来区分代码层次)

  而当一个.py文件作为模块被导入时,我们可能不希望一部分代码被运行。

2.1 一个.py文件被其他.py文件引用

假设我们有一个const.py文件:

PI = 3.14

def main():
     print(“PI:”,PI)

main()

area.py文件,调用const中的PI:

from const import PI

def cal_round_area(radius):
     return PI*(radius**2)


def main():
    print("round area:",calc_round_area(2))


main()

运行结果:

PI:3.14
round area : 12.56

2.2 修改const.py,添加if __name__=='__main__'

运行 area.py,输出:

round area: 12.56

如上,if __name__ == '__main__'相当于python模拟的程序入口,由于模块之间相互引用,不同模块可能有这样的定义,而程序入口只有一个,到底哪个程序入口被选中,取决于__name__的值。

3. __name___

3.1 __name__反映一个包的结构

__name__是内置变量,可用于反映一个包的结构,假设如下结构,a、b是文件夹目录:

在c.py、__init__.py、__init__.py的内容都为: print(__name__)

当执行导入命令:

python -c "import a.b.c"

输出结果:

a

a.b

a.b.c

由此可见,__name__可以清晰反映一个模块在包中的层次。

3.2 __name__表示当前模块的名字

__name__是内置变量,可用于表示当前模块的名字。我们直接运行一个py文件

python a/b/c.py

输出:

__main__

由此可知:如果一个py文件被直接运行时,则其没有包结构,其__name__值为__main__,即模块名为__main__

所以,if__name__== '__main__'的意思是:当py文件被直接运行时,if__name__=='__main__'之下的代码将被运行;当py文件以模块形式被导入时,if __name__=='__main__'之下的代码块不被运行。

4、__main__.py文件与python -m

Python的-m参数用于将一个模块/包作为一个脚本运行,而__main__.py相当于一个包的入口程序

4.1 运行Python程序的两种方式

直接运行xxx.py文件: python xxx.py

把xxx.py当做模块运行: python -m xxx.py

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

import sys
print(sys.path)

 python  run.py

输出结果:

['E:\Pythonwork\...\test_name\a',....]

python -m run.py

输出结果:

【...】

C:ProgramDataAnaconda3python.exe: Error while finding module specification for 'run.py' (ModuleNotFoundError: __path__ attribute not found on 'run'

结论:

  • 直接运行是把run.py文件所在目录放到sys.path属性中
  • 以模块方式运行是把你输入命令的目录(当前工作路径,执行run.py的时候不都是在当前目录下执行吗)放到了sys.path属性中

非run文件所在目录下执行:python -m a/run.py,会报错,no module named "a/run",“a/run”是模块名;而 python a/run.py可以成功执行

4.2 __main__.py的作用

假设包b的结构如下:

__init__的文件内容:

__main__的文件内容:

 运行 python -m b结果:

运行 python b的结果:

 总结:

  • 当加上-m的时候,python会把当前工作目录(testname//a)添加到sys.path中;而不加-m时,python则会把脚本所在目录(具体脚本__main__和__init__所在目录b)添加到sys.path中
  • 当加上 -m参数时,python会先将模块或者包导入,然后再执行(__init__用于包的导入,目录下没有__init__文件则不能作为包)
  • __main__.py文件是一个包或者目录的入口程序。不管是用python b还是用python -m b运行,__main__.py文件总是被执行。

        

原文地址:https://www.cnblogs.com/zzc-Andy/p/15211112.html