PEP 299 – 模块中的特殊 __main__() 函数
- 作者:
- Jeff Epler <jepler at unpythonic.net>
- 状态:
- 已拒绝
- 类型:
- 标准跟踪
- 创建日期:
- 2002年8月12日
- Python 版本:
- 2.3
- 发布历史:
- 2006年3月29日
摘要
许多 Python 模块也旨在作为独立脚本调用。本 PEP 提议一个名为 __main__() 的特殊函数应为此目的服务。
动机
应该有一个简单且通用的惯例,用于将模块作为独立脚本调用。
半标准惯例
if __name__ == '__main__':
perform "standalone" functionality
对于像 C 和 C++ 这样的语言的程序员来说,它不清楚。它也不允许在导入模块时调用独立函数。变体
if __name__ == '__main__':
main_function()
有时会看到,但函数没有标准名称,并且由于参数取自 sys.argv,因此无法在不更改所有其他模块看到的参数列表的情况下传递特定参数。(想象一个多线程 Python 程序,其中两个线程希望使用不同的参数列表调用不同模块的独立功能)
提案
“主函数”的标准名称应该是 __main__。当模块在命令行上调用时,例如
python mymodule.py
那么模块的行为就像在模块末尾存在以下行(除了属性 __sys 可能不被使用或假定存在于脚本的其他地方)
if globals().has_key("__main__"):
import sys as __sys
__sys.exit(__main__(__sys.argv))
其他模块可以执行
import mymodule mymodule.__main__(['mymodule', ...])
由 mymodule 记录线程安全问题或其他可能限制使用 __main__ 的问题。(其他问题可能包括使用互斥的 GUI 模块、非共享资源(如硬件设备)、sys.stdin/stdout 的重新分配等)
实施
在 modules/main.c 中,第 385 行附近的块(在 PyRun_AnyFileExFlags 调用之后)将更改为执行上述代码(或其 C 等效代码)。
未解决的问题
- 来自
__main__的返回值是否应被视为退出值?是的。许多
__main__自然会返回None,sys.exit将其转换为“成功”返回码。在那些返回数值结果的函数中,它的行为就像sys.exit()的参数或 C 的 main() 的返回值一样。 - 传递给
__main__的参数列表是否应包括argv[0],还是只包括“实际”参数argv[1:]?包含
argv[0]是为了与sys.argv对称,并方便过渡到新的标准惯例。
拒绝
在 python-dev [1] 上的一次简短讨论中,提出了两个主要的向后兼容性问题,Guido 宣布他反正不喜欢这个想法,因为它“不值得改变(文档、用户习惯等),而且没有什么特别的错误。”
参考资料
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0299.rst