在 python 文件中,我们经常会看到 if __name__ == "__main__"
。那么 if __name__ == "__main__"
是什么?它可以用来干什么呢?下面就来详细解释下。
python 解释器在读取 python 文件时,会设置一些特殊变量的值,其中有一个变量是 __name__
,下面我们通过一些例子来认识下 __name__
。
python 文件作为主程序运行
新建 foo.py
文件。
# foo.py
print("foo's __name__ is set to: {}".format(__name__))
执行 foo.py
文件,输出结果如下:
foo's __name__ is set to: __main__
__name__
被设置成了 __main__
。当一个文件作为主程序运行时,__name__
会被设置成 __main__
。
python 文件作为模块导入
新建 bar.py
文件。
# bar.py
print("bar's __name__ is set to: {}".format(__name__))
对 foo.py
文件进行修改
# foo.py
import bar
print("foo's __name__ is set to: {}".format(__name__))
执行 foo.py
文件,输出结果如下:
bar's __name__ is set to: bar
foo's __name__ is set to: __main__
从结果可以看出,当 bar.py
作为一个模块被导入时,它的 __name__
被设置成了文件的名字 bar
。
当直接执行 bar.py
文件时,输出结果如下:
bar's __name__ is set to: __main__
和直接执行 bar.py
的结果是类似。
__name__
和 __main__
的用法
使用 __name__
和 __main__
最常见的方式如下:
if __name__ == "__main__":
# todo
将 foo.py
和 bar.py
修改成如下:
# foo.py
import bar
print("foo's __name__ is set to: {}".format(__name__))
if __name__ == "__main__":
print("foo.py ran directly")
else:
print('foo.py ran imported')
# bar.py
print("bar's __name__ is set to: {}".format(__name__))
if __name__ == "__main__":
print("bar.py ran directly")
else:
print('bar.py ran imported')
执行 foo.py
文件,输出结果如下:
bar's __name__ is set to: bar
bar.py ran imported
foo's __name__ is set to: __main__
foo.py ran directly
执行 bar.py
文件,输出结果如下:
bar's __name__ is set to: __main__
bar.py ran directly
当执行 foo.py
时,由于 bar.py
是作为模块被导入的,所以 bar.py
的 __name__
为 bar
。而 foo.py
是直接执行的,所以 foo.py
的 __name__
为 __main__
。
文件中包含函数
将 foo.py
和 bar.py
修改成如下:
# foo.py
import bar
print("foo's __name__ is set to: {}".format(__name__))
def foo_func():
print('I am foo_func')
if __name__ == "__main__":
print("foo.py ran directly")
else:
print('foo.py ran imported')
# bar.py
print("bar's __name__ is set to: {}".format(__name__))
def bar_func():
print("I am bar_func")
if __name__ == "__main__":
print("bar.py ran directly")
else:
print('bar.py ran imported')
执行 foo.py
文件,输出结果如下:
bar's __name__ is set to: bar
bar.py ran imported
foo's __name__ is set to: __main__
foo.py ran directly
执行 bar.py
文件,输出结果如下:
bar's __name__ is set to: __main__
bar.py ran directly
从上面两个输出结果可以看出,文件中的函数当我们不显示调用时,并不会执行。
将 foo.py
和 bar.py
修改成如下,在修改后的文件中我们显示调用函数。
# foo.py
import bar
print("foo's __name__ is set to: {}".format(__name__))
def foo_func1():
print('I am foo_func1')
def foo_func2():
print('I am foo_func2')
if __name__ == "__main__":
bar.bar_func1()
foo_func1()
print("foo.py ran directly")
else:
bar.bar_func2()
foo_func2()
print('foo.py ran imported')
# bar.py
print("bar's __name__ is set to: {}".format(__name__))
def bar_func1():
print("I am bar_func1")
def bar_func2():
print("I am bar_func2")
if __name__ == "__main__":
bar_func1()
print("bar.py ran directly")
else:
bar_func2()
print('bar.py ran imported')
执行 foo.py
文件,输出结果如下:
bar's __name__ is set to: bar
I am bar_func2
bar.py ran imported
foo's __name__ is set to: __main__
I am bar_func1
I am foo_func1
foo.py ran directly
执行 bar.py
文件,输出结果如下:
bar's __name__ is set to: __main__
I am bar_func1
bar.py ran directly
总结
__name__
的存在可以使我们更加灵活地控制 python 文件作为主程序执行时应该执行的代码块以及作为模块被导入执行时应该执行的代码块。