__name__是python的一个内置类属性,是标识模块的名字的一个系统变量。
python的模块既可以被调用,也可以独立运行,这点不像C++和C的头文件。
如果当前模块被直接执行(主模块),__name__存储的是__main__
如果当前模块是被调用的模块(被导入),则__name__存储的是py文件名(模块名称)
通过区分__name__存储的值,python就可以分清楚哪些是主函数,进入主函数执行,并且可以调用其他模块中的函数、变量等。
直接运行脚本
在demoA.py文件中,脚本如下:
直接执行demoA.py 时,流程是这样处理的:
在所有代码执行之前,__name__ 变量值被设置为 '__main__'
然后,通过执行 def 语句,函数 main() 和demoA() 的语句被载入
接着,判断if语句 "if __name__ == '__main__'",表达式为true,执行main()函数。而main()函数又调用了funcA() 函数,计算两个数相加,并打印输出结果。
被其它模块调用
如果需要在其它脚本里使用demoA模块的funcA() 函数,比如在demoB.py 里,可以将 demoA.py 作为一个模块导入。
demoB.py 的内容如下:
这时,就有了两个不同的作用域:一个是 demoB 的,另一个是 demoA 的,处理流程如下:
在 demoB.py中,__name__ 变量的值被设置为 '__main__'。当导入 demoA 的时候,Python 就在本地和环境变量 PATH 指向的路径中寻找对应名称的 .py 文件,找到之后,运行导入的文件中的代码。
在demoB中导入demoA的时候,demoA.py自身的 __name__ 变量值就被设置为了 demoA,然后函数 main() 和 funcA() 语句被载入。然而,这一次 if 语句后面的表达式结果为false,所以 main() 函数没有被调用。
导入完毕之后,回到demoB.py 中,现在 demoA 模块中的函数已经被导入到当前的作用域中,于是我们通过 demoA.funcA() 的方式调用函数,这个函数返回的是模块内的变量的值 'demoA'。
如果尝试在 demoB 中打印 __name__ 变量的值,直接执行demoB,也会输出 '__main__',原因在于,这个变量是在 demoB 的作用域中的。