如何动态添加选项到optparser?
我有一个系统,可以修改哪些模块会被加载和运行。这里的“模块”不一定是Python模块,它可以是多个模块的组合。这个程序可以运行模块A和模块B。现在,我想让每个模块都能定义(添加)自己的参数。比如说,模块A想要一个-n的参数,而模块B想要一个-s的参数。但有一个共同的参数-c,是主系统需要的。请问,怎么做比较好呢?
到目前为止,我一直在使用一个单独的optparse.OptionParser实例,并在每个模块初始化时将它传递给它们。这样,模块就可以根据需要修改(添加新参数)。
2 个回答
2
你可以考虑换一个支持子解析器概念的库,比如argparse(反正optparse也要被淘汰了)。这样每个库就可以自己定义解析规则,而主程序只需要把这些规则组合起来就行了。
1
当我遇到这个问题时,我最终使用了一个从 ArgumentParser
类派生的类,这个类增加了注册回调函数的功能,这些回调函数会在参数解析完成后执行:
import argparse
class ArgumentParser(argparse.ArgumentParser):
def __init__(self, *p, **kw):
super(ArgumentParser, self).__init__(*p, **kw)
self._reactions = []
def add_reaction(self, handler):
self._reactions.append(handler)
def parse_known_args(self, args=None, namespace=None):
(args, argv) = super(ArgumentParser, self).parse_known_args(args, namespace)
for reaction in self._reactions:
reaction(args)
return (args, argv)
这样,解析器对象仍然需要传递给所有模块,以便注册它们的命令行选项,但模块可以“自己”对这些选项做出反应:
def arguments_parsed(args):
if args.datafile:
load_stuff(args.datafile)
def add_arguments(ap):
ap.add_argument('--datafile',
help="Load additional input data")
ap.add_reaction(arguments_parsed)
这个方法使用了 argparse
,但用 optparse
也可能实现类似的功能。
这个方法没有经过高级功能的测试,比如子解析器,可能在这些情况下无法工作,但可以很容易地扩展以支持这些功能。