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