Python中的 if __name__ == '__main__' 是干嘛的?

242 阅读3分钟

如果你写过Java,就一定知道 public static void main 这个如绕口令一般的程序入口函数,即使写一个hello world也不可避免:

图片

相比之下 Python 就简单多了,0帧起手,直接 print:

print('Hello World!')

但如果你的Python练习时长超过2周半,就一定见过这样的写法:

图片

不管是教程里的示例、Github上别人的项目、还是AI生成的代码,都可能出现这行判断语句。

看起来很像Java或C++等语言里程序入口的main函数。

可既然Python不需要入口函数,为何还要多此一举加上这一句?

而且,print一下这个  name 变量就会发现,不管放在程序的哪个位置,它的值都是 字符串 'main' ,那么这个 if 条件判断岂不是毫无意义?

图片

先别着急,在搞清楚这行代码前,我先问你个问题:

一个py代码文件,可以怎样执行?

青铜选手都知道,点击IDE里的运行按钮就可以执行一个py文件。

图片

白银选手会告诉你,也可以在控制台下通过python命令执行代码。

图片

假如你达到了黄金以上,肯定还知道,一个py文件也是一个模块,可以像其他库一样被import导入到另一个py文件中。而被导入的同时,文件中的代码也会被执行。

图片

现在,在被导入的代码中输出这个 name 变量,有趣的事情发生了

输出的结果不再是 main,而成了 hello

图片

看到这里,你明白了吗?

双下划线name这个变量:

  • 如果所在代码是直接被运行,不管是通过IDE,还是命令行,它的值都是字符串 main
  • 如果所在代码是被别的代码调用执行,比如作为模块导入,它的值就是所在文件的文件名

所以,if name == 'main': 这个判断,不是用来指定程序的入口,而是判断当前的文件是否是被直接运行

那它有什么用呢?

对于一些既需要直接运行,又可能作为模块被其他代码复用的文件,就可以通过这个判断,来控制在不同情况下执行不同的代码。

另外,也有很多模块,会把调用的示例或者测试的代码放在这个条件判断里,既方便,又不影响使用。

图片

如果只是写一些自己用的小脚本,不会被import,比如课程作业,那就没有这么写的必要了。

不过钻石选手要说了:程序被调用执行的情况并不只有import导入这一种。

比如这个采用进程池创建多进程的代码,如果直接这么运行,你的IDE就会卡到爆炸。

import multiprocessing
def task(n):    print('Processing', n)    return n * n
with multiprocessing.Pool() as pool:    tasks = range(5)    results = pool.map(task, tasks)print(results)

因为每个进程都会重新执行整个脚本,再次创建一堆新的进程,直到榨干你的电脑。

这时候同样可以通过对 name 的判断,让子进程不要执行创建进程的代码:

图片

总结一下:

  • python代码中 name 这个变量的值,在直接运行时是字符串 "main"。
  • 代码在被导入或者创建子进程执行时, name 的值就是所在的文件名。
  • 可以通过 if name == 'main': 条件判断来区分不同的执行方式,增强了代码的灵活性和可维护性。
  • 在初学编程时,可以不去用它,或者简单地照葫芦画瓢。
  • 出于一名程序员的自我修养,应该知其然更知其所以然,并在合适的场景下使用它,让你的代码更加鲁棒和优雅。
  • 测试新人可以学习《测试人的 Python 工具书》书籍《性能测试 JMeter 实战》书籍