1 参考资料
参考资料为知乎问题if __name__ == ‘__main__’ 如何正确理解?下的所有回答,侵删。
2 问题提出
假设我们有one.py和two.py两个py文件:
# one.py
def say_balabala():
print("balabala")
print("I am in one.py!")
# two.py
import one
one.say_balabala()
print("I am in two.py!")
显然,根据代码,我们对于one.py的需求为:存储一个say_balabala()的函数,这个函数的功能是打印balabala。然后打印一段话,说明这是one.py文件。而对于two.py我们的需求为,首先导入one模块,然后使用one模块中的say_balabala()函数来打印balabala,最后打印一段话,说明这是two.py文件。我们单独运行one.py文件,输出
I am in one.py!
可见one.py达到了我们的需求。继续单独运行two.py,输出为
I am in one.py!
balabala
I am in two.py!
显然,two.py除了完成了我们的需求外,还额外运行了one.py中的print(“I am in one.py!”)语句,这显然是冗余的,违背了我们的需求。
首先我们对two.py冗余打印的产生原因进行分析:在运行two.py时,当运行import one这一语句时会从头到尾运行一遍one.py文件,所以我们不仅能调用one.py中的say_balabala()函数,也会运行one.py中的print(“I am in one.py!”)语句,导致运行two.py时输出只属于one.py的I am in one.py!,而且由于import one语句位于two.py的最上端,连print(“I am in two.py!”)语句的运行都在它的后面。
3 解决方式
更改one.py文件,增加
if __name__ == "__main__":
这一段if表达式,更改后的one.py文件为:
# one.py
def say_balabala():
print("balabala")
if __name__ == "__main__":
print("I am in one.py!")
这样,我们单独运行one.py。在这种情况下,Python的内置__name__变量的值为__main__,if表达式成立,print语句会运行,输出为:
I am in one.py!
这是符合我们对于one.py的需求的,不仅定义了函数say_balabala(),也打印了I am in one.py!语句。而当我们单独运行two.py时,按照之前所述,import one时one.py中的所有语句会执行,但是由于我们是单独运行two.py,没有直接运行one.py,类似于“调用”地,间接地运行one.py。在这种情况下,__name__变量的值不再为main,而是one.py的文件名,即one,这样if表达式显然不会成立,print(“I am in one.py!”)也不会运行。此时two.py的运行结果为
balabala
I am in two.py!
符合我们对于two.py的需求。这样,通过加入这种if表达式,两个文件的需求都被满足了。
4 结语
本博客基于各知乎大佬的回答和我自己的理解完成,本人水平较低,如果错误或不严谨的地方欢迎大家进行指正。