17

可能重复:
<if __name__==“__main__”:> 做什么?

所以我启动了 pyscripter,我得到了一个文件,里面有这个:

def main():
    pass

if __name__ == '__main__':
    main()

那是什么?为什么我的程序没有它也能工作?无论如何,这样做的目的是什么?我的代码会去哪里?让我们说一个打印 hello world 的函数。那会去哪里?我会在哪里称呼它?

4

5 回答 5

14

目的基本上是您可以定义一个中央入口点,当且仅当脚本直接自行运行。因为只有在它自己运行时__name__才会等于。'__main__'将脚本的实际内容放入单独的函数中,可以让其他脚本导入该函数并在需要时运行它,因此在导入脚本时它不会立即运行。

这也经常用于库模块中,以便在您快速需要某些东西时具有一些默认行为。例如,该http.server模块提供了广泛的功能来创建您自己的 HTTP 服务器,具有您能想到的任何功能。如果您只想快速让一个简单的服务器侦听并静态传​​递文件,则可以在从命令行运行时使用模块的默认行为。

在命令行上运行python3 -m http.server将完全做到这一点;运行该http.server模块,它本身将在其__name__ == '__main__块中启动一个简单的 HTTP 服务器。

回应您的评论:

对于充当库、包含类型或函数的普通模块,您的应用程序需要,您不需要main函数或主块。对于直接调用的脚本,例如实际启动应用程序的启动脚本,您将拥有某种未封装在函数或类中但直接运行的代码。那将是一些东西,您可以放入一个 main 函数,然后单独调用该函数。这使您可以更自由地放置该代码。例如,您可以将main函数直接放在文件的开头,而在其中调用的其他函数则在文件中进一步定义。脚本的最后一部分是main(). 您不一定需要将其放入if __main__ == '__main__':条件,你可以直接调用它。例如,您的脚本可能如下所示:

def main ():
    # doing something
    utilityFunction(...)
    otherUtilityFunction(...)

def utilityFunction (...):
    ...
def otherUtilityFunction (...):
    ...

main()

如果您不将代码放入单独的函数中,则必须在底部进行所有处理(在函数定义之后),如果您只想快速查看当直接调用脚本。

现在,正如我所说,您不需要将其放入 main-condition 块;你可以直接调用它。但是,如果出于某种原因您需要包含该文件,例如因为您想将它封装到其他东西中,或者如果您想从交互式 shell(IDLE 或其他东西)重复调用它,您可能不会想要main()在您只导入模块时运行,但仅在您想要实际执行其功能时运行。那就是您应该将其main()放入条件的地方;这样除非您直接执行模块,否则它不会被执行。

一般来说,总是将main()调用置于这种条件下并不是一个坏主意,因为它永远不会受到伤害,但通常会在以后的某个时候变得有用。

于 2012-11-10T16:38:03.260 回答
4

当你执行一个 python 文件时,__name__全局设置为__main__,而当你导入文件时,它设置为它的名称。

该结构允许您仅在执行文件时执行某些代码。例如,如果您有文件mymain.py

def main():
    print('Hello, World!')


if __name__ == '__main__':
    main()

你得到这个结果:

$ python mymain.py
Hello, World!
$ python
Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymain    # main() *not* executed
>>> mymain.main()
Hello, World!

能够在不执行代码的情况下导入文件通常很有用。通过这种方式,第三方软件可以调用 main 函数,而无需创建新进程并允许他们在运行之前更改一些内容。

因此,这不是必需的,但使用它是一种好习惯。通常您会意识到程序的某些函数/类可能对其他程序有用,因此能够在不执行主程序的情况下导入文件是一种好习惯。

与 Java 相比,拥有一个if __name__ == '__main__':块就像拥有一个只有一个main方法并使用其他类来完成他的工作的类,而不使用它就像main在一个类中拥有一个还提供其他功能的方法(例如某种容器或其他还有一个main执行主程序的方法)。

于 2012-11-10T16:39:20.817 回答
2

Python 中的一切都是语句,没有声明之类的东西(例如,adef是创建函数对象并将其绑定到名称的语句)。导入模块意味着(在一些簿记之后)执行模块中的语句。同样,执行 Python 文件意味着将其作为模块导入。因此,只需将程序编写为模块级语句即可。

但当然,这是不可重复使用的。当“程序”也应该可以导入其他模块时,您可以将它放在一个函数中(还有一些其他的小优点)。但随后执行文件 ( python file.py) 只会定义该函数。

Enter __name__,这是模块名称,等于'__main__'“入口点”模块。所以条件检查模块是否被导入或作为脚本运行,并在后一种情况下完成它的工作。

于 2012-11-10T16:40:26.360 回答
0

对于“Hello world”,您实际上并不需要这个技巧,但它在您编写模块时很有用。该if __name__ == '__main__'子句main()仅在脚本直接执行时才运行,而不是在用作从另一个脚本的导入时运行。

于 2012-11-10T16:38:28.843 回答
0

这个想法很简单:您可以将文件用作包(要在某处导入的东西)或纯脚本。如果文件用作脚本,Python 的解释器变量“ __name__”包含“ __main__”而不是包的名称。

因此,我们测试是否__name__设置为__main__,这意味着我们处于脚本模式,如果是,我们执行“if”块中的代码。

您必须了解 Java 和 Python 之间的一个主要区别:在 Python 中,当解释器读取文件时,它会被执行 --> 声明和代码都被解释,Python 的许多特性都基于此。

于 2012-11-10T16:45:14.820 回答