我有一个系统,您可以在其中修改,将加载哪些模块(并运行;“模块”不一定是python模块,它可以组合多个模块)。程序可以运行模块A和B.现在,我希望有一个选项,每个模块都可以定义(添加)自己的参数。让我们说A希望有-n和B想要-s用于某事。但是有一个常见的参数-c,主系统本身需要它。实现这一目标的最佳方法是什么?
到目前为止,我一直在使用单个optparse.OptionParser实例,并在初始化时将其传递给每个模块。然后,如果需要,模块可以修改(添加新参数)。
答案 0 :(得分:2)
您应该考虑转移到支持子解析器概念的库,例如argparse(无论如何都弃用了optparse),这样每个库都可以创建自己的解析器规则,主程序可以将它们组合起来。
答案 1 :(得分: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
可能也是如此。
它没有使用subparsers等高级功能进行测试,可能无法在那里工作,但可以很容易地进行扩展。