有没有办法在argparse
中指定两个必需参数,一个对应于一个子命令,另一个是所有子命令所需的。
我能管理得最近的似乎是
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='', dest='command', metavar='COMMAND', title='required arguments',
description='two arguments are required')
parser.add_argument('config', metavar='CONFIG', action='store', help='the config to use')
cmda_parser = subparsers.add_parser('cmdA', help='a first command')
cmdb_parser = subparsers.add_parser('cmdB', help='the second operation')
cmdc_parser = subparsers.add_parser('cmdC', help='yet another thing')
print(parser.parse_args())
给出了
usage: enigma.py [-h] COMMAND ... CONFIG
positional arguments:
CONFIG the config to use
optional arguments:
-h, --help show this help message and exit
required arguments:
two arguments are required
COMMAND
cmdA a first command
cmdB the second operation
cmdC yet another thing
并帮助显示未显示CONFIG
的子命令;但我想要的是
usage: enigma.py [-h] COMMAND CONFIG
required arguments:
two arguments are required
COMMAND
cmdA a first command
cmdB the second operation
cmdC yet another thing
CONFIG the config to use
optional arguments:
-h, --help show this help message and exit
并帮助显示CONFIG
的每个子命令,例如
usage: enigma.py cmdA CONFIG [-h]
required arguments:
CONFIG the config to use
optional arguments:
-h, --help show this help message and exit
有没有办法实现这个目标?
如何具体两个必需参数,其中一个是子命令,第二个“传播”到每个子命令作为必需参数?
答案 0 :(得分:1)
Parsers可以使用parents
属性从其他解析器“继承”参数。
import argparse
parser = argparse.ArgumentParser()
# Put common subparser arguments here. Each sub parser will have
# its own -h option, so disable it on the shared base.
subbase = argparse.ArgumentParser(add_help=False)
subbase.add_argument('config', metavar='CONFIG', action='store', help='the config to use')
subparsers = parser.add_subparsers(help='', dest='command', metavar='COMMAND', title='required arguments',
description='two arguments are required')
# Add subbase to the parent list for each subparser.
cmda_parser = subparsers.add_parser('cmdA', parents=[subbase], help='a first command')
cmdb_parser = subparsers.add_parser('cmdB', parents=[subbase], help='the second operation')
cmdc_parser = subparsers.add_parser('cmdC', parents=[subbase], help='yet another thing')
print(parser.parse_args())
答案 1 :(得分:0)
使用您定义的解析器,COMMAND
和CONFIG
都是必需的。试试例子
python myprog cmdA
你应该得到错过的参数错误。在较新的版本上它将是明确的
0826:~/mypy$ python3.5 stack33463052.py cmdA
usage: stack33463052.py [-h] COMMAND ... CONFIG
stack33463052.py: error: the following arguments are required: CONFIG
但是,是的,COMMAND
没有出现在subparser的帮助中。那是因为subparse对此一无所知。它是为主解析器定义的。
如果我将CONFIG
定义移到subparsers
创建之前,我会得到:
0833:~/mypy$ python stack33463052.py tst cmdA -h
usage: stack33463052.py CONFIG cmdA [-h]
optional arguments:
-h, --help show this help message and exit
现在CONFIG
出现在用法中。那是因为在定义subparser时代码知道这个参数。但是 - 在寻求帮助时我必须为CONFIG
添加一个值。
(编辑)
CONFIG
用法中显示cmdA
,因为在创建解析器时,它已添加到prog
属性中:
print(cmda_parser.prog)
'stack33463052.py CONFIG cmdA'
但如果稍后将参数添加到prog
,则不会修改parser
。
在下文中,cmdA
被视为CONFIG
的参数,而不是COMMAND
,因此我获得了默认的主解析器帮助。
0833:~/mypy$ python stack33463052.py cmdA -h
usage: stack33463052.py [-h] CONFIG COMMAND ...
positional arguments:
CONFIG the config to use
optional arguments:
...
对于主解析器,CONFIG
和COMMAND
都是必需的定位器。 COMMAND
没有什么特别之处,只有它有3个已定义的choices
。
为每个子分析器定义CONFIG
可能是最佳选择。它需要更多输入,但它将显示在正确的帮助中。如果从概念上讲它与命令的关联比主解析器更紧密,那么它需要用它们来定义。所有命令都需要它的事实并不那么重要。
通常,在使用子分析程序时,最好使用主要解析器值(如vebosity和logging)的选项,并在子分配器中定义其余部分。它使解析器之间的工作分工更加清晰。如果需要,我可以详细说明。
没有传播机制。但我当然可以写一个函数,为每个subparser添加一个共同的参数。
def foo(subparsers, *args, **kwargs):
sub = subparsers.add_parser(*args, **kwargs)
sub.add_argument('config')
return sub
在交互式shell中运行解析器设置并检查每个命令创建的对象 - parser
,subparsers
,cmda_parser
等是有益的。参数列表parser
知道的(操作对象)位于parser._actions
中。
argparse
模块中的程序清晰度和简洁性意味着parser
和cmda_parser
是不同的ArgumentParser
个对象。一个不仅仅是另一个的模式或方法。 subparsers
对象(Action子类)是parser
和cmda_parser
之间唯一的正式链接。
还可以尝试:
parser.print_help() # or parser.print_usage()
cmda_parser.print_help()
这有助于显示2个解析器的help
是独立的。