if __name__ == "__main__" 是什么意思?
本文解释了 Python 代码表达式if __name__ == '__main__' 的含义。
Python 程序使用条件 `if __name__ == '__main__'` 仅在程序由 Python 解释器 直接运行时才执行 if 语句内的代码。当文件的代码作为模块导入时,if 语句内的代码不会被执行。
什么是 __main__?
"__name__" 在 Python 中表示一个特殊的变量。
Python 有许多以双下划线开头和结尾的特殊变量。为了简便起见,它们被称为 dunder(来自 Double Underscores)。在本例中,"__name__" 读作“dunder name”。
让我们使用 Python shell 来确定 __main__ 的值:
>>> __name__ '__main__'
因此,__name__ 的值为 __main__。
让我们尝试导入一个 Python 模块,看看分配给模块的 __name__ 变量的值:
>>> import random >>> random.__name__ 'random'
因此,导入 random 模块 后,我们可以看到 __name__ 的值为 'random',这实际上就是它的名称。
Python __name__ 变量的值
编写以下代码并将其放在文件 __name__main.py 中:
print(" __name__ value is {}".format(__name__))
一条使用字符串格式化方法输出 __name__ 值的 print 命令。
当我们直接引用 Python 文件运行代码时,__name__ 的值为 __main__:
$ python __name__main.py The value of __name__ is __main__
相反,如果我们通过 Python shell 导入模块,__name__ 的值为 __name__main:
>>> import _name_main __name__ value is __name__main
因此,__name__ 的值取决于我们 Python 代码的执行方式。
__name__ 的示例
要在 Python 中使用条件 `if __name__ == "__main__"`,我们创建一个如下所示的 Python 程序,其中调用三个不同的函数:
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") step1() step2() step3()
输出
以下是上述代码的输出:
Executing the first step... Executing the second step... Executing the third step...
假设另一个 Python 应用程序需要使用 step1() 函数。我们需要将我们的文件作为模块导入来实现这一点。
当我们这样做时会发生什么:
>>> import _name_main Executing the first step... Executing the second step... Executing the third step... >>> _name_main.step1() Executing the first step...
导入模块后,可以调用 step1() 函数。问题是,当我们导入模块时,以下三行会自动执行:
step1() step2() step3()
现在问题是——我们如何阻止这种情况发生?
检查模块导入时 __name__ 是否等于 __main__
我们可以检查 __name__ 的值是否等于 "__main__" 来阻止上一节中看到的行为。
这样,只有在直接调用 Python 文件而不是将其作为模块导入时,if 条件内的代码才会运行。
示例
现在,程序是:
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") if __name__ == "__main__": step1() step2() step3()
输出
让我们检查一下直接调用 Python 程序是否仍然会调用这三个函数。
Executing the first step... Executing the second step... Executing the third step...
此外,当我们将其作为模块导入时,这三个函数不会被执行;
>>> import _name_main >>> _name_main.step1() Executing the first step...
这次好多了!
假设 _name_main 模块有数百个函数,并非所有函数都需要导入。
如何只导入 step1() 函数?
应使用以下语法:
>>> from _name_main import step1 >>> step1() Executing step1... >>> step2() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'step2' is not defined
如您所见,在本例中,我们只导入了 step1 函数的成功版本。
当我们尝试运行 step2() 时,会发生 `NameError: name 'step2' is not defined` 错误。
Python 中的主方法
在像 Java 或 C 这样的语言中,main 的概念非常常见,它指定程序执行的起点。
在 Python 中经常使用的main()函数在 if 语句内执行,并检查 __name__ 变量的值。
为了获得特定的结果,main() 函数中调用了几个函数。在本例中,main 函数将调用三个子函数:
示例
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") def main(): step1() step2() step3() if __name__ == "__main__": main()
输出
Executing the first step... Executing the second step... Executing the third step...
由于 main 的概念也为其他开发人员所熟知,因此将函数命名为 main() 只是一种标准的命名约定,可以提高程序的可读性。
实际上,没有任何东西阻止我们将 main 函数重命名为其他名称。
在继续本文之前,请验证我们修改后的代码在两种情况下都能正常工作:
- 直接执行代码
- 导入模块
__name__、__main__ 和 Python 中的参数
当在确定变量 __name__ 是否等于 "__main__" 的 if 条件内直接调用我们的 Python 程序时,我们可以处理传递给程序的任何参数。
我们可以使用sys 模块来处理传递给程序的参数。
导入 sys 模块。
创建一个名为 main() 的函数,它只接受一个参数。这个参数将是一个包含传递给程序的参数的字符串列表。
作为 if 语句的一部分(该语句检查 __name__ 变量的值),将 sys.argv 传递给 main() 函数。
示例
import sys def main(args): print(args) if __name__ == "__main__": main(sys.argv)
输出
以下是上述已执行程序的输出:
['main.py']
如您所见,Python 程序的第一个参数是 .py 文件本身的名称。
让我们修改 main 方法,使其打印 args 变量的类型。
def main(args): print(type(args)) print(args)
这证明了 args 是一个列表:
$ python arguments.py arg1 arg2 <class 'list'> ['arguments.py', 'arg1', 'arg2']
除了提供参数外,我们还可以解包程序需要的参数,不包括程序的名称:
import sys def main(c, d): return int(c) * int(d) if __name__ == "__main__": arg1, arg2 = sys.argv[1:3] print(main(arg1, arg2))
以下是我们执行程序的步骤以及我们获得的结果:
$ python product.py 4 5 20
这段代码使用切片运算符获取命令行上提供的两个数字。然后将这两个数字以字符串格式传递给 main() 方法。
然后,main 函数返回这两个数字转换为整数的结果。