从外部模块添加argparse参数

7 投票
2 回答
2402 浏览
提问于 2025-04-18 07:30

我正在尝试写一个可以被第三方扩展的Python程序。这个程序会从命令行运行,并接受用户提供的各种参数。

为了让第三方能够创建自己的模块,我创建了一个简化的基础类:

class MyBaseClass(object):
    def __init__(self):
        self.description = ''
        self.command = ''

    def get_args(self):
        # code that I can't figure out to specify argparse arguments here
        # args = []
        # arg.append(.....)
        return args

他们通过get_args()提供的任何参数都会被添加到特定模块的子解析器中。我希望他们能够指定任何类型的参数。

我不太确定如何最好地声明这些参数,然后把它们从子类模块获取到我的主程序中。我成功找到了所有MyBaseClass的子类,并循环遍历它们来创建子解析器,但我找不到一个干净的方法来将各个参数添加到子解析器中。

这是主程序当前的代码:

for module in find_modules():
    m = module()
    subparser_dict[module.__name__] = subparsers.add_parser(m.command, help=m.help)
    for arg in m.get_args():
            subparser_dict[module.__name__].add_argument(...)

我该如何通过get_args()或类似的方法在外部模块中最好地指定参数,然后将它们添加到子解析器中?我之前的一次失败尝试看起来像这样,但它不工作,因为它试图将每一个可能的选项都传递给add_argument(),无论它是否有值或者是None:

            subparser_dict[module.__name__].add_argument(arg['long-arg'],
                action=arg['action'],
                nargs=arg['nargs'],
                const=arg['const'],
                default=arg['default'],
                type=arg['type'],
                choices=arg['choices'],
                required=arg['required'],
                help=arg['help'],
                metavar=arg['metavar'],
                dest=arg['dest'],
                )

2 个回答

3

我建议你在你的 get_args 方法中返回一个 ArgumentParser 的实例。这样,你就可以创建一个新的 ArgumentParser,并通过 parents 参数把其他所有的参数解析器连接起来。具体可以参考这个链接:https://docs.python.org/3/library/argparse.html#parents

4

在不深入了解你的模块结构的情况下,我觉得你想要的是能够把参数以对象的形式提供给一个 add_argument 的调用,这样你就可以导入它们。

比如,你可以提供一个位置参数的列表和一个关键字参数的字典:

args=['-f','--foo']
kwargs={'type':int, 'nargs':'*', 'help':'this is a help line'}

parser=argparse.ArgumentParser()
parser.add_argument(*args, **kwargs)
parser.print_help()

这样就会产生

usage: ipython [-h] [-f [FOO [FOO ...]]]

optional arguments:
  -h, --help            show this help message and exit
  -f [FOO [FOO ...]], --foo [FOO [FOO ...]]
                        this is a help line

argparse.py 文件中,add_argument 方法(这是 ArgumentParser 的一个父类的方法)大致是这个样子的:

def add_argument(self, *args, **kwargs):

这个方法的代码会处理这些参数,把 args 加到 kwargs 中,添加默认值,最后把 kwargs 传递给合适的 Action 类,并返回新的动作。(它还会把这个动作“注册”到解析器或子解析器中)。实际上,Action 子类的 __init__ 方法会列出参数及其默认值。

撰写回答