我们可以将自己的类型添加到解析器的注册表中,例如:
from argparse import ArgumentParser
from distutils.util import strtobool
parser = ArgumentParser('flats')
parser.register('type', 'boolean', strtobool)
parser.add_argument('--conveyor-belt', type='boolean')
到目前为止,这是可行的,即args = parser.parse_args(['--conveyor-belt', 'on'])
然后args.conveyor_belt == True
。但在尝试添加子Parser时:
subparsers = parser.add_subparsers()
subparser = subparsers.add_parser('slaughterhouse')
subparser.add_argument('--rotating-knives', type='boolean') # crash
我们在这里得到错误:ValueError 'boolean' is not callable
。你知道吗
我希望所有子parser自动继承父级已注册的类型。可能吗?你知道吗
几年前,我在这里演示了
register
的用法。你知道吗Parsing boolean values with argparse
它不是一个隐藏的特性(即没有“\”),但也没有文档记录。你知道吗
每个解析器都有一个
registry
,它将字符串与类和函数相匹配。如果action='store_true'
,解析器在registry
中查找“store\u true”,并找到相应的Action
子类。你知道吗type
字符串也会被查找,不过默认情况下只注册“None”。其他常见的类型值,如int
和float
,是Python函数,不需要注册。你知道吗子解析器是使用主解析器类的新解析器。我不认为它们使用它的任何
__init__
参数,当然它们也不使用任何在创建之后可能已经更改的属性。你知道吗可以定义一个
ArgumentParser
子类,将这些项添加到注册表中。你知道吗argparse.py
代码的一些相关部分:因此,主解析器的类用
subparsers
Action
对象记录,并且在创建子解析器时使用。但是像description
和help_formatter
这样的参数是从add_parser
命令获取的,而不是继承的。有一个bug/问题要求继承formatter_class
,但没有执行任何操作。你知道吗从您的代码:
以及
或者不必
update
,只需共享字典:argparse
做了很多属性共享。例如,_actions
列表在parser
和它的所有action_groups
之间共享。你知道吗因此,如果我要将它添加到
argparse
,或者我自己的版本中,我可能会修改_SubParsersAction
类而不是ArgumentParser
类。或者只是定义一个助手函数:据我所知,
subparsers
没有任何对主解析器的引用。也就是说,subparsers
在parser._actions
列表中,但是没有其他方向的链接。你知道吗更改子角色动作类
parser._defaults
是另一个没有从主解析器传递到子解析器的属性。它是用set_defaults
设置的,记录如下:https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.set_defaults
在子Parser中设置不同的值作为将函数链接到子Parser的一种方式进行记录:
https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_subparsers
从这里关于subparser的问题来看,很明显这个特性非常有用。但它也有点棘手的使用,并不是每个人都喜欢。你知道吗
最初的作者Steven J.Bethard编写的最后一个补丁与在主解析器和子解析器之间传递
Namespace
有关。你知道吗argparse set_defaults on subcommands should override top level set_defaults
但这不是每个人都喜欢的。你知道吗
argparse - subparsers does not retain namespace
根据当前的问题,我建议使用
register
来使用定制的_SubParsersAction
,这很有趣。你知道吗这是必需的,因为正如上面的
add_subparsers
引号所示,argparse
使用注册表来确定要使用的子类。你知道吗有人可能会说
parser.register
的这种用法需要记录在案。但我不知道如何才能做到这一点,而不会给不需要该功能的用户带来困惑。你知道吗相关问题 更多 >
编程相关推荐