可以组合两个 Python argparse 对象吗? [英] Can two Python argparse objects be combined?

查看:32
本文介绍了可以组合两个 Python argparse 对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an object A which contains parserA - an argparse.ArgumentParser object There is also object B which contains parserB - another argparse.ArgumentParser

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

Object A contains an instance of object B, however object B's arguments now need to be parsed by the parser in object A (since A is the one being called from the command line with the arguments, not B)

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

Is there a way to write in Python object A: parserA += B.parserB?

推荐答案

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

argparse was developed around objects. Other than a few constants and utility functions it is all class definitions. The documentation focuses on use rather than that class structure. But it may help to understand a bit of that.

parser = argparse.ArgumentParser(...)

创建一个 parser 对象.

arg1 = parser.add_argument(...)

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

creates an argparse.Action (subclass actually) object and adds it to several parser attributes (lists). Normally we ignore the fact that the method returns this Action object, but occasionally I find it helpful. And when I build a parser in an interactive shell I see a this action.

args = parser.parse_args()

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

runs another method, and returns an namespace object (class argparse.Namespace).

组方法和子解析器方法还创建和返回对象(组、动作和/或解析器).

The group methods and subparsers methods also create and return objects (groups, actions and/or parsers).

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

The ArgumentParser method takes a parents parameter, where the value is a list of parser objects.

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

parsera的创建过程中,parserb中的actions和groups被复制到parsera.这样,parsera 将识别 parserb 所做的所有参数.我鼓励你测试它.

during the creation of parsera, the actions and groups in parserb are copied to parsera. That way, parsera will recognize all the arguments that parserb does. I encourage you to test it.

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

But there are a few qualifications. The copy is by reference. That is, parsera gets a pointer to each Action defined in parserb. Occasionally that creates problems (I won't get into that now). And one or the other has to have add_help=False. Normally a help action is added to a parser at creation. But if parserb also has a help there will be conflict (a duplication) that has to be resolved.

但是如果 parsera 是独立于 parserb 创建的,则不能使用 parents.没有从 parserb 添加操作的现有机制.有可能制作一个新的解析器,两者都作为父母

But parents can't be used if parsera has been created independently of parserb. There's no existing mechanism for adding Actions from parserb. It might possible to make a new parser, with both as parents

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

我可能会写一个函数,将 parserb 的参数添加到 parsera,借鉴实现 parents 的方法的想法.但我必须知道如何解决冲突.

I could probably write a function that would add arguments from parserb to parsera, borrowing ideas from the method that implements parents. But I'd have to know how conflicts are to be resolved.

查看 argparse._ActionsContainer._add_container_actions 以了解参数(操作)如何从 parent 复制到 parser.可能令人困惑的是,除了位于 parser.

Look at the argparse._ActionsContainer._add_container_actions to see how arguments (Actions) are copies from a parent to a parser. Something that may be confusing is that each Action is part of a group (user defined or one of the 2 default groups (seen in the help)) in addition to being in a 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)

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

With this each parser handles the arguments it knows about, and returns the rest in the extras list.

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

Unless the parsers are designed for this kind of integration, there will be rough edges with this kind of integration. It may be easier to deal with those conficts with Arnial's approach, which is to put the shared argument definitions in your own methods. Others like to put the argument parameters in some sort of database (list, dictionary, etc), and build the parser from that. You can wrap parser creation in as many layers of boilerplate as you find convenient.

这篇关于可以组合两个 Python argparse 对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆