在学习python的过程中,经常会看到下面这样的代码:
def sub_funt(): #...if __name__ == "__main__": sub_func()
其中第5行通过一个if判断语句之后调用了函数sub_func,那么这里的__name__和__main__是干什么的?作用是什么呢?下面我们通过示例说明。
__name__是python的内置属性,是系统全局变量,每一个py源代码都有一个属于自己的__name__,但是在具体使用过程中__name__常常依据当前代码具体使用情况会有两种值:
当前源文件没有导入(import)到其他源代码中,直接测试运行时,此时__name__的值为“__main__”;
当前源文件导入(import)到其他代码中,当其他代码运行时,被导入的源文件中的__name__值为该源文件的文件名;
__main__用来表示当前顶层执行时代码环境的名字,当该顶层代码从标准输入、脚本解释器中被读取时,__name__就会被设置为字符串“__main__”;
其实__main__和__name__的关系就像梅西在其他关心了解他的地球人眼里(import)的名字(__name__)是“球王”,但是在梅西自己眼中的名字(__name__)是(__main__)梅西。
【示例】
def my_name(): print ("My name is",__name__)if __name__ == "__main__":print ("In w_name.py __name__ is",__name__)my_name()else: print ("Imported by other module!")
【仿真结果】
示例中,“__main__”和__name__相等,输出对应的消息,通过输出结果可以观测到__name__的值为“__main__”。因为此时该源文件本身作文顶层被执行,此时的__name__值为“__main__”。那么该源文件中的__name__是否会一直是“__main__”呢?请看下例。
【示例】
from w_name import *if __name__ == "__main__": print ("In top_tb.py __name__ is",__name__) my_name()
【仿真结果】
示例中,top_tb.py中的__name__的值为“__main__”,而此时w_name.py中的__name__的值为w_name.py的文件名,即“w_name”,因为w_name.py此时import到了top_tb.py中,此时top_tb.py作为顶层被调用,w_name.py被import到top_tb.py中,此时w_name.py并未作为顶层调用,其中__name__的值已经不是“__main__”了。由此可见,w_name.py中的__name__的值取决于该模块是否作为顶层调用。
通过上述几个示例,“if __name__ == “__main__””可以作为当前文件模块的(类似于C程序中的main函数)入口,尤其在大型的设计中常常需要这样的入口表明程序开始运行的入口。另外,随着源程序越来越复杂,必然有很多模块文件组成,经常在编写完一个源程序后需要进行不断的测试,使用“if __name__ == “__main__””这种方式就可以巧妙的实现单个源文件的测试,同时对于该源文件导入到其他源文件不产生任何影响。正如上述两例,第一个示例w_name.py单独测试时,__name__和“__main__”相等,此时定义的子程序my_name会被调用,可以实现对于子程序my_name的调试。第二个示例中,top_tb.py导入(import)了w_name.py中的内容,此时w_name.py中的__name__中的值为w_name.pyde文件名,“if __name__ == “__main__””不满足,子程序my_name不会被调用,但是在top_tb.py中,__name__和“__main__”相等,条件表达是成立,其后的语句会被执行。即采用“if __name__ == “__main__””的方式在python模块中可以实现对于单独源文件的测试(将要测试的代码放在if之后),同时对于调用导入其的源程序不产生任何影响。
本文纯属学习之用,欢迎指正文中不足,
封面图片若有侵权,请及时沟通!
推荐书目如下!