我有以下示例设置:
|-- main_script.py
`-- module
|-- __init__.py
`-- submodule.py
其中main_script的内容为:
import optparse
import module
parser = optparse.OptionParser()
group = optparse.OptionGroup("submodules options")
group.add_option("","--main_script.bar", dest="bar", action="store_true")
parser.add_option_group(group)
opts,args = parser.parse_args()
if opts.bar:
print ("Bar")
和submodule.py的内容是:
import optparse
parser = optparse.OptionParser()
group = optparse.OptionGroup(parser, "submodules options")
group.add_option("","--module.submodule.foo", dest="foo", action="store_true")
parser.add_option_group(group)
opts,args = parser.parse_args()
if opts.foo:
print ("Foo")
由于main_script导入子模块,因此调用了子模块中的parse_args。无论如何,如果存在选项冲突,那么组合这些OptionParser实例并引发错误吗?
答案 0 :(得分:2)
最简单的方法是将逻辑分解为函数。您不应该首先在全局模块范围内执行逻辑,而是使用if name == "__main__"
包装器构造。
您可以为每个必须定义选项的模块定义一个函数add_options(parser)
,并在调用parse_args
之前在根级别调用它:
import optparse
import submodule
def add_options(parser):
parser.add_option(...)
def main():
parser = optparse.OptionParser()
add_options(parser)
submodule.add_options(parser)
opts, args = parser.parse_args()
#...
if __main__ == "__main__":
main()
答案 1 :(得分:0)
试图从外部解决这个问题 - 我有一个初始实现,通过用OptionParser的子类替换OptionParser类来修补optparse模块,并重载parse_args方法+暴露一个新的delayed_parse_args方法。我正在分享此解决方案的片段,以防其他人发现它有用或可以对其进行改进。
<强> optparse_patch.py 强>
import optparse
def patch_opt_parser():
optparse.stashed_parsers = {}
class OptionParserEx(optparse.OptionParser):
def delayed_parse_args(self, callback):
optparse.stashed_parsers[self] = callback
def parse_args(self, args=None, values=None):
for parser, callback in getattr(optparse,"stashed_parsers").items():
# add all the option_list & option_groups from the individual
# parsers in stashed_parsers to `self`
for parser, callback in getattr(optparse,"stashed_parsers").items():
# update `parser` to inherit the option_lists and option_groups from
# self. then ....
_o, _a = optparse._OptionParser.parse_args( parser, args, values )
callback( _o, _a t)
return getattr(optparse,"_OptionParser").parse_args(self, args, values)
optparse._OptionParser = optparse.OptionParser
optparse.OptionParser = OptionParserEx
patch_opt_parser()
这允许子模块“隐藏”它们的预期选项,并在模块的客户端实际提供OptionParser并在其自己的OptionParser上调用parse_args方法时,在稍后阶段评估命令行选项。这种用例的一个例子如下:
<强> module.py 强>
import optparse_patch
import optparse
parser = optparse.OptionParser()
group = optparse.OptionGroup(parser, "module options")
group.add_option("-f", dest="flip", action="store_true")
parser.add_option_group(group)
def cli_callback ( opts, args ):
if opts.flip:
print "flip"
opts, args = parser.delayed_parse_args ( cli_callback )
<强> main.py 强>
import module
import optparse
myparser = optparse.OptionParser()
mygroup = optparse.OptionGroup(myparser, "main options")
mygroup.add_option("-j", dest="jump", action="store_true")
myparser.add_option_group(mygroup)
opts, args = myparser.parse_args()
if opts.jump:
print "jump"
调用程序main.py会产生以下输出:
python main.py --help
Usage: main.py [options]
Options:
-h, --help show this help message and exit
module options:
-f
main options:
-j
python main.py -j -f
flip
jump