所以我启动了 pyscripter,我得到了一个文件,里面有这个:
def main():
pass
if __name__ == '__main__':
main()
那是什么?为什么我的程序没有它也能工作?无论如何,这样做的目的是什么?我的代码会去哪里?让我们说一个打印 hello world 的函数。那会去哪里?我会在哪里称呼它?
所以我启动了 pyscripter,我得到了一个文件,里面有这个:
def main():
pass
if __name__ == '__main__':
main()
那是什么?为什么我的程序没有它也能工作?无论如何,这样做的目的是什么?我的代码会去哪里?让我们说一个打印 hello world 的函数。那会去哪里?我会在哪里称呼它?
目的基本上是您可以定义一个中央入口点,当且仅当脚本直接自行运行。因为只有在它自己运行时__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()
调用置于这种条件下并不是一个坏主意,因为它永远不会受到伤害,但通常会在以后的某个时候变得有用。
当你执行一个 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
执行主程序的方法)。
Python 中的一切都是语句,没有声明之类的东西(例如,adef
是创建函数对象并将其绑定到名称的语句)。导入模块意味着(在一些簿记之后)执行模块中的语句。同样,执行 Python 文件意味着将其作为模块导入。因此,只需将程序编写为模块级语句即可。
但当然,这是不可重复使用的。当“程序”也应该可以导入其他模块时,您可以将它放在一个函数中(还有一些其他的小优点)。但随后执行文件 ( python file.py
) 只会定义该函数。
Enter __name__
,这是模块名称,等于'__main__'
“入口点”模块。所以条件检查模块是否被导入或作为脚本运行,并在后一种情况下完成它的工作。
对于“Hello world”,您实际上并不需要这个技巧,但它在您编写模块时很有用。该if __name__ == '__main__'
子句main()
仅在脚本直接执行时才运行,而不是在用作从另一个脚本的导入时运行。
这个想法很简单:您可以将文件用作包(要在某处导入的东西)或纯脚本。如果文件用作脚本,Python 的解释器变量“ __name__
”包含“ __main__
”而不是包的名称。
因此,我们测试是否__name__
设置为__main__
,这意味着我们处于脚本模式,如果是,我们执行“if”块中的代码。
您必须了解 Java 和 Python 之间的一个主要区别:在 Python 中,当解释器读取文件时,它会被执行 --> 声明和代码都被解释,Python 的许多特性都基于此。