如何重构一个使用 argparse 的脚本以便在另一个 Python 脚本中调用?

How do I refactor a script that uses argparse to be callable inside another Python script?

我有一个查找测试名称的脚本,在我们公司广泛使用。它像这样在命令行上运行:

find_test.py --type <type> --name <testname>

在脚本中相当于:

import argparse

parser = argparse.ArgumentParser(description='Get Test Path')
parser.add_argument('--type',      dest='TYPE',      type=str,            default=None,  help="TYPE [REQUIRED]")
parser.add_argument('--name',      dest='test_name', type=str,            default=None,  help="Test Name (Slow)")
parser.add_argument('--id',        dest='test_id',   type=str,            default=None,  help="Test ID (Fast)")
parser.add_argument('--normalise', dest='normalise', action="store_true", default=False, help="Replace '/' with '.' in Test Name")
args = parser.parse_args()

(不确定所有这些参数的作用,我个人只使用前两个)。然后这些行由使用这些参数的代码处理。

我想重构这个脚本,这样我就可以将它作为一个模块导入,同时保留它的命令行功能 - 因为很多人使用这个脚本,而且它也在我们的一些 csh 脚本中被调用。

到目前为止我已经重构了它,像这样:

def _main():
    <all the former code that was in find_test.py>

if __name__ == "__main__":
    _main()

这在命令行中仍然运行良好。但我不知道我如何在我的父脚本中将带有相关开关的参数传递给它。

如何进一步重构它然后在父脚本中调用它? 这可能吗?

我也宁愿不使用 docopts,我读过它是新的 argparse,除非有必要 - 即不能用 argparse 完成,因为它没有在公司范围内安装,这可能是一个艰巨的过程。

你不应该把所有的代码直接移到一个函数中;那根本没用。

您应该做的是将需要 运行 的代码移到一个函数中。 (而且因为它是外部接口,它不应该以 _ 开头。)只需要从命令行 运行 的代码——即解析器的东西——应该 保留 __name__ == '__main__' 块中,它应该将其结果传递给 main().

所以:

def main(TYPE, test_name, test_id=None, normalise=False):
    # ... body of script...

if __name__ == "__main__":
    parser = ...
    ...
    args = parser.parse_args()
    main(**vars(args))

(docopt 并不是什么新鲜事物;它是一些人喜欢的外部库。)