Python 如何向OptPasser动态添加选项?
我有一个系统,您可以在其中修改哪些模块将被加载(并运行;“module”不一定是python模块,它可以组合几个模块)。程序可以运行模块A和B。现在,我想有一个选项,每个模块都可以定义(添加)自己的参数。假设A想要-n,B想要-s。但是有一个共同的参数——c,这是主系统本身所需要的。实现这一目标的最佳方式是什么Python 如何向OptPasser动态添加选项?,python,configuration,module,code-organization,Python,Configuration,Module,Code Organization,我有一个系统,您可以在其中修改哪些模块将被加载(并运行;“module”不一定是python模块,它可以组合几个模块)。程序可以运行模块A和B。现在,我想有一个选项,每个模块都可以定义(添加)自己的参数。假设A想要-n,B想要-s。但是有一个共同的参数——c,这是主系统本身所需要的。实现这一目标的最佳方式是什么 到目前为止,我一直在使用单个optparse.OptionParser实例,并在初始化模块时将其传递给每个模块。然后,如果需要,模块可以修改(添加一个新的参数)。 < P>您应该考虑移到
到目前为止,我一直在使用单个optparse.OptionParser实例,并在初始化模块时将其传递给每个模块。然后,如果需要,模块可以修改(添加一个新的参数)。 < P>您应该考虑移到支持子分析器的概念的库中,例如(不推荐optPARSE),这样每个库可以创建它自己的解析器规则,主程序可以将它们组合起来。当我遇到这个问题时,我最终使用了一个派生自
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)
这样,解析器对象仍然需要传递给所有模块以注册其命令行开关,但模块可以“自行”对开关作出反应:
这使用了argparse
,但同样的方法也可以使用optparse
它没有使用诸如Subparser之类的高级功能进行测试,可能在那里不起作用,但可以很容易地进行扩展。您目前的操作方式有什么问题吗?@sth-当前的解决方案看起来一团糟。首先,我将解析器传递给模块以添加参数。稍后我必须得到参数的值。这是可行的,而且有点有效。我只是在寻找更优雅的解决方案,如果有的话。我坚持使用Python2.6。即使我使用了argparse,您仍然建议我使用相同的体系结构,将解析器发送到每个模块(在本例中,它将是父解析器)?子解析器仅在您希望每个模块实现子命令时有用,如
svn commit
与svn checkout
等。。如果您只想添加一个命令行开关子parser,那根本没有帮助。感谢您提供的示例,我将对此进行研究。我目前有一个模块(conf)和一个配置类实例(变量名conf)。此配置类具有optparse对象(变量optionparser)。因此,我可以轻松访问它conf.conf.optionparser.add_option(…)
。在主体部分开始运行之前,我解析选项以使用它们。这有意义吗?不管怎样,我会接受你的回答,因为它给了我一些新的想法,而且回调的想法很有价值。
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)