如何动态添加选项到optparse?

时间:2011-08-01 14:35:11

标签: python configuration module code-organization

我有一个系统,您可以在其中修改,将加载哪些模块(并运行;“模块”不一定是python模块,它可以组合多个模块)。程序可以运行模块A和B.现在,我希望有一个选项,每个模块都可以定义(添加)自己的参数。让我们说A希望有-n和B想要-s用于某事。但是有一个常见的参数-c,主系统本身需要它。实现这一目标的最佳方法是什么?

到目前为止,我一直在使用单个optparse.OptionParser实例,并在初始化时将其传递给每个模块。然后,如果需要,模块可以修改(添加新参数)。

2 个答案:

答案 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等高级功能进行测试,可能无法在那里工作,但可以很容易地进行扩展。