对于一个小模块,我希望有一个__main__.py
文件,通过Python的-m
参数执行。根据基本文档,该文件看起来像
import argparse
from . import MyClass
def getparser():
parser = argparse.ArgumentParser()
# […]
return parser
if __name__ == "__main__":
parser = getparser()
args = parser.parse_args()
c = MyClass()
# […]
我想用runpy测试一下:
import runpy
def test_main():
runpy.run_module("mymodule")
# […]
因为在这种情况下__name__
不是__main__
,所以这不起作用。原则上,可以省略if __name__ == "__main__"
条件以使其工作。
但是,我还想用sphinxarg.ext记录这个例程。这需要从sphinx获得getparser()
函数。删除if __name__ == "__main__"
条件也会在sphinxdoc中运行模块,这不是我们想要的。
.. argparse::
:module: mymodule.__main__
:func: getparser
:prog: myprog
我该如何构建它,以便所有用例都能很好地工作***并且***代码可读性良好(即``getparser()`函数和主代码不应该分布在不同的文件中)?
1条答案
按热度按时间ufj5ltwl1#
一种方法是保持
__main__.py
非常精简,并导入所需的内容并运行它。因此,您可以将逻辑提取到另一个模块中,比如
cli.py
,并编写一个main
函数,其功能与您在if __name__ == '__main__':
下的代码块相同。然后在
__main__.py
中,您可以简单地拥有类似于此的东西,它将与runpy
一起工作(尽管现在可能没有必要!),并且不需要sphinx或测试模块来导入它:这样,您仍然可以从
cli.py
(或您选择的任何地方)导入所有内容,测试它,自动记录它,或其他任何内容。使用这种方法,您还可以测试main
函数,而不会受到使用runpy
进行测试时出现的限制。提取到
cli.py
这样的模块在技术上是可选的。您也可以在__main__.py
中保留所有这些,但主要的教训是最大限度地减少if __name__ == '__main__':
下的代码量。如果我有这个,它几乎总是看起来像这样:您也可以简单地使用
runpy.run_module
的run_name
关键字参数设置__name__
:但是我建议提取一个可测试的
main
函数是一种更好的测试方法。