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

时间:2016-06-27 09:54:03

标签: python python-2.7 argparse

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

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

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

2 个答案:

答案 0 :(得分:8)

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

parser = argparse.ArgumentParser(...)

创建一个parser对象。

arg1 = parser.add_argument(...)

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

args = parser.parse_args()

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

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

ArgumentParser方法采用parents参数,其中值是解析器对象列表。

使用

parsera = argparse.ArgumentParser(parents=[parserb])

在创建parsera期间,parserb中的操作和群组会被复制到parsera。这样,parsera将识别parserb所做的所有参数。我鼓励你测试它。

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

但如果parents独立于parsera创建,则parserb无法使用parserb。从parserc = argparse.ArgumentParser(parents=[parsera, parserb]) 添加操作没有现有的机制。可以创建一个新的解析器,同时作为父项

parserb

我可能会编写一个函数来添加parseraparents的参数,借用实现argparse._ActionsContainer._add_container_actions的方法的思路。但我必须知道如何解决冲突。

查看parent,了解参数(操作)如何从parser复制到group。可能令人困惑的是,除parser之外,每个Action都是[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) (用户定义的或2个默认组中的一个(见帮助中)之一)的一部分。

另一种可能性是使用

extras

有了这个,每个解析器处理它所知道的参数,并返回Arnial's列表中的其余部分。

除非解析器是为这种集成而设计的,否则这种集成会有粗糙的边缘。使用╔═══════════════╦═══════════════╦═══════════════╗ ║ CodTipoMoneda ║ idTipoCuenta ║ Saldo ║ ╠═══════════════╬═══════════════╬═══════════════╣ ║ 002 ║ 10 ║ 854 ║ ║ 003 ║ 21 ║ 500 ║ ║ 002 ║ 10 ║ 500 ║ ║ 002 ║ 22 ║ 680 ║ ║ 003 ║ 20 ║ 130 ║ ║ 002 ║ 30 ║ 10 ║ ║ 003 ║ 12 ║ 2 ║ ╚═══════════════╩═══════════════╩═══════════════╝ 方法处理这些混淆可能更容易,即将共享参数定义放在您自己的方法中。其他人喜欢将参数参数放在某种数据库(列表,字典等)中,并从中构建解析器。您可以将解析器创建包装在尽可能多的样板文件层中。

答案 1 :(得分:2)

您无法在另一个内部使用一个ArgumentParser。但有一种方法可以解决。您需要提取到为解析器添加参数的方法代码。 然后,您将能够使用它们在解析器中合并参数。 此外,将参数分组(与其解析器相关)也更容易。但你必须支持那些参数名称不相交的部分。

示例:

foo.py:

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

if __name__ = "__main__":  
   parser = argparse.ArgumentParser(prog='Foo')

boo.py

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

if __name__ = "__main__":  
   parser = argparse.ArgumentParser(prog='Boo')

fooboo.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 )