你做对了。但也许我可以解释一些细节。
a = parser.add_argument(...)
add_argument
创建一个Action
对象(或者实际上是一个子类,具体取决于action
范围)。您可以在自己的环境中保存指向该对象的指针。但该 Action 也收集在parse._actions
列表。就是这样的parser
记录其论点。
Reading _actions
应该永远是安全的。修改它可能会破坏解析器。argument_groups
有权访问该列表。
subparsers = parser.add_subparsers(dest="command")
是一个专门版本add_argument
,创建并返回一个argparse._SubParsersAction
目的。subparsers
是那个物体。正如之前的答案所述,您可以在_actions
通过搜索正确的子类来列出。 (对于主解析器,subparsers
只是另一个位置参数。)
subparsers
维护自己的专业词典parsers
,可作为其访问choices
属性。主解析器没有这些子解析器的任何记录。
parser_other = subparsers.add_parser("other")
创建一个解析器,将其放入其中choices
映射,并返回一个引用供您自己使用(带有add_argument
ETC)。每个子解析器都有自己的_actions
列表。 (以及它自己的_defaults
).
查看代码get_defaults
method:
def get_default(self, dest):
for action in self._actions:
if action.dest == dest and action.default is not None:
return action.default
return self._defaults.get(dest, None)
它使用_actions
属性。并看着action.default
动作的属性。
self._defaults
字典是由parser.set_defaults
方法。该方法还将其参数复制到相关的 Action 对象。get_defaults
检查万一dest
是与特定操作无关的默认值之一。https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.set_defaults
我没用过parser._subparsers
属性多。看着parser.add_subparsers
方法我看到它实际上是一个argument_group
。 Argument_groups 主要是help
工具,用于对帮助热线进行分组。解析器对象与其 argument_groups 之间的关系有点棘手,可能不是您想要使用的。
这是一个包含更多(太多)细节的示例:
In [22]: parser = argparse.ArgumentParser()
In [23]: sp = parser.add_subparsers(title='subparsers', dest='cmd')
In [24]: sp1 = sp.add_parser('cmd1')
In [25]: sp2 = sp.add_parser('cmd2')
In [26]: parser.print_help()
usage: ipython3 [-h] {cmd1,cmd2} ...
optional arguments:
-h, --help show this help message and exit
subparsers:
{cmd1,cmd2}
In [28]: [a.dest for a in parser._actions]
Out[28]: ['help', 'cmd']
In [29]: parser._action_groups
Out[29]:
[<argparse._ArgumentGroup at 0xaf86bf2c>,
<argparse._ArgumentGroup at 0xaf86bdcc>,
<argparse._ArgumentGroup at 0xac99fa6c>]
In [30]: [g.title for g in parser._action_groups]
Out[30]: ['positional arguments', 'optional arguments', 'subparsers']
In [31]: parser._subparsers
Out[31]: <argparse._ArgumentGroup at 0xac99fa6c>
The _defaults
of _subparsers
实际上是同一个字典parser._defaults
In [32]: parser.set_defaults(extra='foobar')
In [33]: parser._defaults
Out[33]: {'extra': 'foobar'}
In [34]: parser._subparsers._defaults
Out[34]: {'extra': 'foobar'}
parser._subparsers._actions
也与parser._actions
。但该组确实维护自己的列表操作(在帮助显示中使用)。
In [35]: parser._subparsers._group_actions
Out[35]: [_SubParsersAction(option_strings=[], dest='cmd', nargs='A...', const=None,
default=None, type=None, choices=OrderedDict([...]), help=None, metavar=None)]
所以你可以使用parser._subparsers._group_actions[0]
找到subparsers
动作对象而不是搜索parsers._actions
list.
In [37]: parser._subparsers._group_actions[0].choices
Out[37]:
OrderedDict([('cmd1',
ArgumentParser(prog='ipython3 cmd1', usage=None, description=None,...)),
('cmd2',
ArgumentParser(prog='ipython3 cmd2', usage=None, description=None,...))])
再一想,parser._subparsers._group_actions
可能没那么有用。如果你不给它一个特殊的标题,那么它与parser._positionals
,所有位置参数的参数组。所以你仍然需要验证_SubParsersAction
class.