当 Python 解释器读取一个 Python 文件时,它首先设置一些特殊变量,然后执行文件中的代码。

其中一个变量叫作 __name__

如果你一步步地阅读本文,并阅读了下列代码片段,你将明白 if __name__ == "__main__" 的用法,以及它为什么如此重要。

Python 模块介绍

Python 文件被称为模块,具有 .py 文件扩展名标识。可以用模块来定义函数、类和变量。

因此,当解释器运行模块时,如果正在运行的模块是主程序,则 __name__ 变量将被设置为 __main__

但是,如果代码是从另一个模块导入模块,则 __main__ 变量将被设置为该模块的名称。

让我们看一个例子。创建一个名为 file_one.py 的 Python 模块,并将以下顶层代码粘贴到其中:

# Python file one module

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

运行这个文件,你就会明白这是什么意思。模块中的变量 __name__ 被设置为 __main__

File one __name__ is set to: __main__

现在,添加另一文件,名为 file_two.py,并粘贴以下代码:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))
file_two.py

同时,修改 file_one.py 中的代码如下,这样我们就导入了 file_two 模块:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

再次运行 file_one 代码,会显示 file_one 中的 __name__ 变量未改变,仍然是被设置为 __main__。但是现在 file_two 中的变量 __name__ 被设置为它的模块的名字,即 file_two

结果如下:

File two __name__ is set to: file_two
File one __name__ is set to: __main__

直接运行 file_two,你会看到它的名字被设置为 __main__

File two __name__ is set to: __main__

运行的文件/模块的变量 __name__ 将始终为 __main__。但是,正在导入的所有其他模块的  __name__ 变量将被设置为其模块的名称。

Python 文件命名约定

使用 __name____main__ 的常规方式是:

if __name__ == "__main__":
   Do something here

让我们看看在实际代码中如何使用这些变量。

修改 file_onefile_two

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
file_one.py

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

同样,在运行 file_one 时,你将看到程序识别出这两个模块中的哪个是 __main__,并根据我们的第一个 if else 语句执行了代码。

结果如下:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly

现在,运行 file_two,你会看到 __name__ 变量被设置为 __main__

File two __name__ is set to: __main__
File two executed when ran directly

当这样的模块被导入并运行时,它们的函数将被导入,并执行顶层代码。

要查看此过程的实际效果,请将文件修改为如下所示:

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
file_one.py

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")

现在,函数被加载了,但未运行。

要运行其中一个函数,修改 file_oneif __name__ == "__main__" 为:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
else:
   print("File one executed when imported")

当运行 file_one 时,你应该会看到:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed

同样,从导入文件运行函数。将 file_oneif __name__ == “__main__” 修改为:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   file_two.function_three()
else:
   print("File one executed when imported")

你应该会得到这个结果:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed
Function three is executed

现在,假设 file_two 模块确实具有很多函数(在我们的示例中有两个),并且你不想导入所有这些函数。修改 file_two 如下所示:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

def function_four():
   print("Function four is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

要从模块导入特定的函数,需要使用 file_onefrom 导入块:

# Python module to execute
from file_two import function_three

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   function_three()
else:
   print("File one executed when imported")
file_one.py

总结

无论你想要一个可以作为主程序运行还是可以由其他模块导入的文件,都可以使用 __name__ 变量。 我们可以使用 if __name__ == "__main__" 在模块导入时来允许或阻止运行部分代码。

当 Python 解释器读取文件时,如果正在运行模块,则将 __name__ 变量设置为 __main__;如果导入了模块,则将其设置为模块的名称。读取文件将执行所有顶级代码,但不会执行函数和类(因为它们只会被导入)。

很棒!

欢迎阅读我在 freeCodeCamp 专栏的更多文章,以及查看我在 GitHub page 构建的其他有趣的东西。

原文:Python if __name__ == __main__ Explained with Code Examples,作者:Goran Aviani