为啥 def main(argv=[__name__]) 和 if __name__ == "__main__": sys.exit(main(sys.argv))?

Posted

技术标签:

【中文标题】为啥 def main(argv=[__name__]) 和 if __name__ == "__main__": sys.exit(main(sys.argv))?【英文标题】:Why def main(argv=[__name__]) and if __name__ == "__main__": sys.exit(main(sys.argv))?为什么 def main(argv=[__name__]) 和 if __name__ == "__main__": sys.exit(main(sys.argv))? 【发布时间】:2017-05-19 08:12:07 【问题描述】:

我正在使用/重写一个首先定义如下函数的代码:

def main(argv=[__name__]):
    ...
    *rest of code*
    ...

并以:

结尾
if __name__ == "__main__":
    sys.exit(main(sys.argv))

我的印象是,它所做的是检查以确保从命令行执行脚本,然后在退出 python 时使用提供的参数运行函数main。但是,为什么要在函数定义中将变量argv预设为[__name__]呢?这不是我的代码,所以我不知道这背后的初衷。但是,我对使用 if __name__ == "__main__": 行来抽查命令行执行情况并不陌生,所以我缺少这种语法可能有一些明显的原因。任何有关main 函数定义和参数/命令行-vs-模块测试的帮助或更多详细信息将不胜感激。

【问题讨论】:

sys.exit() 没有任何奇怪之处,我们的知识库中已经有(回答!)关于那里使用的做法的问题,比较 __name____main__。请考虑缩小您的问题范围,不再有重复的部分;可以说,跨越预先回答和未回答的问题使其“过于宽泛”。 ...其中的一个例子:Why use def main()? 【参考方案1】:

main() 定义允许以文件底部的sys.exit() 行以外的其他方式调用main()。这可能是防御性编程的示例,也可能表明此文件的其他支持用途。

另一个受支持的用法可能是从另一个 Python 程序调用它,如下所示:

import your_module
your_module.main()

【讨论】:

【参考方案2】:

至于argv=[__name__],最初的开发者可能希望保留运行此功能的选项,而不是从命令行(即由另一个模块调用),并提供__name__,因为它使用sys.argv[0] 来实现某些功能.

main 函数与 python 无关,只是一些约定(源自 C 等语言)。 sys.exit(main(sys.argv)) 将触发 sys.exit 函数,其退出代码等效于使用接收到的命令行参数运行 main 函数的产物。 main 可能应该返回一个适当的退出代码(0 表示 OK,其他则暗示各种异常)。

【讨论】:

嗯...有趣。原始代码在main() 函数中根本不使用sys.arvg[0] 或argv 的任何元素。如果此函数作为模块而不是在命令行之外运行,是否会像这样定义 argv 确保 main() 函数始终使用将其作为模块调用的脚本的命令行参数中特定的参数? 如果该函数不使用argv,那么使用它作为参数是没有意义的。否则,您可以通过发送自定义参数来控制主要功能(或确保它们与默认的 argv 一起存在)【参考方案3】:

从 CLI 运行脚本时,argv[0] 是脚本的名称,argv 的其余部分是命令行参数。所以main() 的其余部分可能期望argv[0] 将始终被填写。

默认值是确保argv[0] 在导入文件而不是直接运行时具有类似的内容。在这种情况下,它是模块的名称。

【讨论】:

以上是关于为啥 def main(argv=[__name__]) 和 if __name__ == "__main__": sys.exit(main(sys.argv))?的主要内容,如果未能解决你的问题,请参考以下文章

main中的python命令行参数,跳过脚本名称

Python 第二十二章

python 启动 mitmdump

关于__init__ __main__ __name__等的使用

如何设置显示内容而不是显示对象

为啥我不能在 main.py 中使用 kivy 添加图像?