当你直接执行一段脚本的时候,这段脚本的 __name__变量等于 '__main__',当这段脚本被导入其他程序的时候,__name__ 变量等于脚本本身的名字。
下面,让我举两个栗子来说明一下:
情况 1 - 直接运行脚本
假设我们有一个name.py,代码如下:
def myFunction():
print('变量 __name__ 的值是 ' + __name__)
def main():
myFunction()
if __name__ == '__main__':
main()
当你直接执行 name.py 时,流程是这样处理的:
在所有其他代码执行之前,__name__变量就被设置为 '__main__' 了。在此之后,通过执行 def 语句,函数 main() 和 myFunction() 的本体被载入。
接着,因为这个 if 语句后面的表达式为真 true,函数 main() 就被调用了。而 main() 函数又调用了myFunction(),打印出变量的值'__main__'。
情况 2 - 从其他脚本里导入
如果你需要在其他脚本里重用这个 myFunction() 函数,比如在 importing.py 里,我们可以将 name.py 作为一个模组导入。
假设 importing.py 的内容如下:
import name as ns
ns.myFunction()
这时,我们就有了两个不同的作用域:一个是 importing 的,一个是 name 的。让我画个示意图,你就能看出这和之前的区别了:
在 importing.py 里,__name__ 变量就被设置为 '__main__'。当导入 name 的时候,Python 就在本地和环境变量 PATH 指向的路径中寻找对应名称的 .py 文件,找到之后,将会运行导入的文件中的代码。
但这一次,在导入的时候,它自身的 __name__ 变量就被设置为了 'name',接下来还是一样,函数 main() 和 myFunction() 的本体被载入。然而,这一次 if 语句后面的表达式结果为假 false,所以 main() 函数没有被调用。
导入完毕之后,回到 importing.py 中。现在 name 模块中的函数定义已经被导入到当前的作用域中,于是我们通过 ns.myFunction() 的方式调用模块中的函数,这个函数返回的是模块内的变量的值 'name'。
如果你试着在 importing 中打印 __name__ 变量的值,那当你直接执行 importing 的时候,它也会输出 '__main__'。原因在于,这个变量是在 importing 的作用域中的。
总结
今天和大家一起讨论了 __name__ 变量在模组中的特性,分析了不同的调用方式对它的值有什么影响。利用这个特性,你既可以在程序中导入模组来使用,也可以直接把模组本身作为程序来运行。