Python 中的 if __name__ == '__main__' 的作用

先看官方解释 __main__ — Top-level code environment — Python 3.12.2 documentation

__main__ --- 顶层脚本环境

'__main__' 是顶层代码执行的作用域(scope)的名称。模块的 __name__ 在通过标准输入、脚本文件或是交互式命令读入的时候会等于 '__main__'。

模块可以通过检查自己的 __name__ 来得知是否运行在 main 作用域中,这使得模块可以在作为脚本或是通过 python -m 运行时条件性地执行一些代码,而在被 import 时不会执行。

if __name__ == "__main__":
    # execute only if run as a script——仅当作为脚本运行时执行
    main()

对软件包来说,通过加入 __main__.py 模块可以达到同样的效果,当使用 -m 运行模块时,其中的代码会被执行。

不知所言何意?别急,看懂下面之后,再回头看吧。

在Python当中,如果代码写得规范一些,通常会写上一句“if __name__==’__main__:”作为程序的入口,但似乎没有这么一句代码,程序也能正常运行。这句代码多余吗?原理又在哪里?

__name__属性是Python的一个内置属性,记录了一个字符串:

☆若是在当前文件,__name__ 是__main__

demoPI.py文件,内容如下

PI = 3.14
print(__name__) #__name__的理解演示

运行之,参见下图:

python if语句中的变量是局部变量还是全局变量_Python

☆若是导入的文件,__name__是模块名

现在,我们有一个demoArea.py文件,用于计算圆的面积,该文件里边需要用到前面提到的demoPI.py文件中的 PI 变量,demoArea.py文件内容如下:

from demoPI import PI

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

def funB():
    print("圆的面积: ", calcArea(3))

funB()
print(__name__) #__name__的理解演示

运行demoArea.py,参见下图:

python if语句中的变量是局部变量还是全局变量_python_02

由此可知,一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名,如果当前模块时被直接执行,__name__的值就是__main__。也就是说,通过__name__的值,我们可以判断出该模块是作为脚本正在执行还是被其他模块导入,而根据这个判断,我们就可以选择性地执行代码。

现在可以看看“if__name__=='__main__':”的意思了。

当运行“if __name__=='__main__':”语句时,如果当前模块时被直接执行,__name__的值就是__main__,条件判断的结果为True,“if __name__=='__main__':”下面的代码块就会被执行。

demoAdd.py文件内容如下:

def add(a,b):
    return a+b

if __name__ == '__main__':
    c = add(2,3) #计算2+3
    print(c)

直接运行demoAdd.py文件,将会输出

5

demoAdd2.py文件内容如下:

from demoAdd import add
e = add(8,9)
print(e)

运行demoAdd2.py文件,将会输出

17

如果将demoAdd.py文件内容改为:

def add(a,b):
    return a+b

c = add(2,3) #计算2+3
print(c)

现在运行demoAdd2.py文件,将会输出

5
17

请注意体会在demoAdd.py文件中if __name__ == '__main__':有无的作用。

总之,通常情况下,将一些希望在脚本作为主程序执行时执行的代码放在 if __name__ == '__main__': 语句块中,这样可以确保这部分代码仅在脚本被直接运行时执行,而在被导入时不会执行。