如何从 python 脚本设置 argparse 参数

How to set argparse arguments from python script

我在包的 setup.py 中指定了一个 main 函数作为入口点,它使用 argparse 包来传递命令行参数(参见 discussion here) :

# file with main routine specified as entry point in setup.py
import argparse
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('a', type=str, help='mandatory argument a')
    args = parser.parse_args()

理想情况下,我想在包的测试中使用相同的 main 功能,如建议的那样 here。在后一种情况下,我想从测试 class 中调用 main 函数并在函数调用之前设置(某些)命令行参数(否则会失败,因为缺少参数)。

# file in the tests folder calling the above main function
class TestConsole(TestCase):
    def test_basic(self):
        set_value_of_a()
        main()

这可能吗?

argparse模块实际上是从特殊变量中读取输入变量,称为ARGV(简称ARGument Vector)。通常通过从 sys 模块读取 sys.argv 来访问此变量。

这个变量是一个普通列表,因此您可以像这样将命令行参数附加到它:

import sys
sys.argv.extend(['-a', SOME_VALUE])
main()

然而,在运行时乱用 sys.argv 并不是一个好的测试方法。 在某些有限范围内替换 sys.argv 的更简洁的方法是使用 unittest.mock.patch 上下文管理器,如下所示:

with unittest.mock.patch('sys.argv'. ['-a', SOME_VALUE]):
    main()

Read more about unittest.mock.patch in documentation

此外,检查这个 SO 问题:

How do I set sys.argv so I can unit test it?

kwargs 添加到 main,如果它们是 None,则将它们设置为 parse_args

@William Fernandes:为了完整起见,我将 post 按照以下建议的方式提供完整的解决方案(检查空字典而不是 kwargs is None):

def main(**kwargs):
    a = None
    if not kwargs:
        parser = argparse.ArgumentParser()
        parser.add_argument('a', type=str, help='mandatory argument a')
        args = parser.parse_args()
        a = args.a
    else:
        a = kwargs.get('a')

    print(a)

在测试 class 中,可以使用参数调用 main 函数:

# file in the tests folder calling the above main function
class TestConsole(TestCase):
    def test_basic(self):
        main(a=42)

没有 kwargs 的命令行调用需要指定命令行参数 a=...