我有一个包含 parserA 的对象 A - 一个 argparse.ArgumentParser 对象 还有一个包含 parserB 的对象 B - 另一个 argparse.ArgumentParser
对象 A 包含对象 B 的一个实例,但是对象 B 的参数现在需要由对象 A 中的解析器解析(因为 A 是从命令行使用参数调用的对象,而不是 B)
有没有办法在Python对象A中写成:parserA += B.parserB?
最佳答案
argparse
是围绕对象开发的。除了一些常量和实用函数外,它都是类定义。该文档侧重于使用而不是类结构。但这可能有助于理解其中的一点。
parser = argparse.ArgumentParser(...)
创建一个解析器
对象。
arg1 = parser.add_argument(...)
创建一个 argparse.Action
(实际上是子类)对象并将其添加到多个 parser
属性(列表)中。通常我们会忽略该方法返回此 Action 对象这一事实,但偶尔我会发现它很有用。当我在交互式 shell 中构建解析器时,我看到了这个 Action 。
args = parser.parse_args()
运行另一个方法,并返回一个命名空间对象(class argparse.Namespace
)。
组方法和子解析器方法也创建和返回对象(组、 Action 和/或解析器)。
ArgumentParser
方法接受一个parents
参数,其中值是解析器对象的列表。
与
parsera = argparse.ArgumentParser(parents=[parserb])
在parsera
的创建过程中,parserb
中的 Action 和组被复制到parsera
中。这样,parsera
将识别 parserb
所做的所有参数。我鼓励您对其进行测试。
但是有一些条件。副本是引用。也就是说,parsera
获得一个指向每个在 parserb
中定义的 Action 的指针。偶尔会产生问题(我现在不谈)。其中之一必须有 add_help=False
。通常在创建时将帮助操作添加到解析器。但是,如果 parserb
也有帮助,就会出现必须解决的冲突(重复)。
但是如果 parsera
是独立于 parserb
创建的,则不能使用 parents
。没有用于从 parserb
添加操作的现有机制。有可能制作一个新的解析器,两者都是 parent
parserc = argparse.ArgumentParser(parents=[parsera, parserb])
我可能会编写一个函数,将参数从 parserb
添加到 parsera
,借鉴实现 parents
的方法的想法。但我必须知道如何解决冲突。
查看 argparse._ActionsContainer._add_container_actions
以了解参数(操作)如何从 parent
复制到 parser
。可能令人困惑的是,除了在 parser中之外,每个 Action 都是
.group
的一部分(用户定义的或 2 个默认组之一(在帮助中看到))
另一种可能性是使用
[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
列表中的其余部分。
除非解析器是为这种集成设计的,否则这种集成会有一些粗糙的边缘。使用 Arnial 的
方法可能更容易处理这些冲突,即将共享的参数定义放在您自己的方法中。其他人喜欢将参数参数放在某种数据库(列表、字典等)中,并从中构建解析器。您可以在方便的时候将解析器创建包装在尽可能多的样板层中。
关于python - 可以组合两个 Python argparse 对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38050873/