来源 | 经授权转自 Crossin的编程教室(ID:crossincode)
如果你写过Java,就一定知道 public static void main 这个如绕口令一般的程序入口函数,即使写一个hello world也不可避免:
相比之下 Python 就简单多了,0帧起手,直接 print:
但如果你的Python练习时长超过2周半,就一定见过这样的写法:
不管是教程里的示例、Github上别人的项目、还是AI生成的代码,都可能出现这行判断语句。
看起来很像Java或C++等语言里程序入口的main函数。
可既然Python不需要入口函数,为何还要多此一举加上这一句?
而且,print一下这个
__name__
变量就会发现,不管放在程序的哪个位置,它的值都是 字符串
'__main__'
,那么这个 if 条件判断岂不是毫无意义?
先别着急,在搞清楚这行代码前,我先问你个问题:
一个py代码文件,可以怎样执行?
青铜选手都知道,
点击IDE里的运行按钮
就可以执行一个py文件。
白银选手会告诉你,也可以在
控制台下通过python命令
执行代码。
假如你达到了黄金以上,肯定还知道,一个py文件也是一个模块,可以像其他库一样被import导入到另一个py文件中。而被导入的同时,文件中的代码也会被执行。
现在,在被导入的代码中输出这个 __name__ 变量,有趣的事情发生了
输出的结果不再是 __main__,而成了 hello
看到这里,你明白了吗?
双下划线name这个变量:
所以,
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__': 条件判断来区分不同的执行方式,增强了代码的灵活性和可维护性。
-
在初学编程时,可以不去用它,或者简单地照葫芦画瓢。
-
出于一名程序员的自我修养,应该知其然更知其所以然,并在合适的场景下使用它,让你的代码更加鲁棒和优雅。