可以组合两个Python argparse对象吗?

Mic*_*alD 7 python python-2.7 argparse

我有一个包含parserA的对象A - 一个argparse.ArgumentParser对象还有一个包含parserB的对象B - 另一个argparse.ArgumentParser

对象A包含对象B的实例,但是对象B的参数现在需要由对象A中的解析器解析(因为A是从命令行调用的参数,而不是B)

有没有办法在Python对象A中编写:parserA + = B.parserB?

hpa*_*ulj 9

argparse是围绕物体开发的.除了一些常量和实用函数之外,它都是类定义.文档侧重于使用而不是类结构.但它可能有助于理解一点.

parser = argparse.ArgumentParser(...)
Run Code Online (Sandbox Code Playgroud)

创建一个parser对象.

arg1 = parser.add_argument(...)
Run Code Online (Sandbox Code Playgroud)

创建一个argparse.Action(实际的子类)对象并将其添加到多个parser属性(列表).通常我们忽略了该方法返回此Action对象的事实,但偶尔我发现它有用.当我在交互式shell中构建解析器时,我看到了这个动作.

args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

运行另一个方法,并返回一个名称空间对象(类argparse.Namespace).

组方法和子分析器方法还可以创建和返回对象(组,操作和/或解析器).

ArgumentParser方法接受一个parents参数,其中值是解析器对象的列表.

parsera = argparse.ArgumentParser(parents=[parserb])
Run Code Online (Sandbox Code Playgroud)

在创建过程中parsera,将操作和组parserb复制到parsera.这样,parsera将识别所有的论据parserb.我鼓励你测试一下.

但是有一些资格.该副本仅供参考.也就是说,parsera获取指向每个Action中定义的Action的指针parserb.偶尔会产生问题(我现在不会进入).一个或另一个必须有add_help=False.通常,在创建时将帮助操作添加到解析器.但如果parserb还有帮助,则必须解决冲突(重复).

parents如果parsera是独立创建的,则不能使用parserb.没有现有的添加动作的机制parserb.可以创建一个新的解析器,同时作为父项

parserc = argparse.ArgumentParser(parents=[parsera, parserb])
Run Code Online (Sandbox Code Playgroud)

我大概可以写会从添加参数的函数parserbparsera,借用实现该方法的想法parents.但我必须知道如何解决冲突.

查看argparse._ActionsContainer._add_container_actions参数(Actions)是如何从a复制parent到a parser.可能令人困惑的是,group除了在a中之外,每个Action都是(用户定义的或2个默认组中的一个(在帮助中看到)之一)的一部分parser.

另一种可能性是使用

[argsA, extrasA] = parserA.parse_known_args()
[argsB, extrasB] = parserB.parse_known_args()  # uses the same sys.argv 
# or
args = parserB.parse_args(extrasA, namespace=argsA)
Run Code Online (Sandbox Code Playgroud)

有了这个,每个解析器处理它知道的参数,并返回extras列表中的其余部分.

除非解析器是为这种集成而设计的,否则这种集成会有粗糙的边缘.使用Arnial's方法处理那些混淆可能更容易,即将共享参数定义放在您自己的方法中.其他人喜欢将参数参数放在某种数据库(列表,字典等)中,并从中构建解析器.您可以在方便的情况下将解析器创建包含在多层样板文件中.


小智 6

你不能ArgumentParser在另一个里面使用一个。但有办法解决。您需要提取到向解析器添加参数的方法代码。然后您将能够使用它们在解析器中合并参数。对参数(与其解析器相关)进行分组也会更容易。但是您必须确信参数名称集不相交。

例子:

foo.py:

def add_foo_params( group ):
   group.add_argument('--foo', help='foo help')

if __name__ = "__main__":  
   parser = argparse.ArgumentParser(prog='Foo')
Run Code Online (Sandbox Code Playgroud)

def add_boo_params( group ):
   group.add_argument('--boo', help='boo help')

if __name__ = "__main__":  
   parser = argparse.ArgumentParser(prog='Boo')
Run Code Online (Sandbox Code Playgroud)

foob​​oo.py

   from foo import add_foo_params
   from boo import add_boo_params

   if __name__ = "__main__":  
       parser = argparse.ArgumentParser(prog='FooBoo')
       foo_group = parser.add_argument_group(title="foo params")
       boo_group = parser.add_argument_group(title="boo params")

       add_foo_params( foo_group )
       add_boo_params( boo_group )
Run Code Online (Sandbox Code Playgroud)