Argparse:具有可变参数的选项的可选参数
Posted
技术标签:
【中文标题】Argparse:具有可变参数的选项的可选参数【英文标题】:Argparse: Optional argument with choices that have variable arguments 【发布时间】:2020-03-16 09:29:38 【问题描述】:我有一个正在尝试改进的 CLI。我想做的是有一个带有 3 个选项的可选参数,根据您的选择,您需要为该选项输入某些参数。
例如:
--create dog DOG_NAME DOG_BREED
OR
--create cat CAT_NAME
OR
--create fish FISH_BREED FISH_TANK
等等
所以这看起来有点像:
parser.add_argument("--create", help="Create an animal", choices=["dog", "cat", "fish"])
但是我如何为每个选项设置不同的必需参数?我必须使用子解析器吗?
编辑:使用稍微不同的架构并让它工作。
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title="actions", dest="subcmd")
subp_create = subparsers.add_parser("create", description="Create a Dog, Cat, or Fish")
subp_delete = subparsers.add_parser("delete", description="Delete a Dog, Cat, or Fish")
subp_create.add_argument("--dog", help="Create a Dog", nargs=2, metavar=(DOG_NAME, DOG_BREED))
#etc.
args = parser.parse_args()
handle_args(args)
def handle_args(args):
if args.subcmd == "create":
if args.dog:
dog_name = args.dog[0]
dog_breed = args.dog[1]
#Do whatever you need
【问题讨论】:
这可能有用:***.com/questions/19414060/… 类似但不完全一样。如果我将其应用于上面的示例,我需要所有可能参数的位置参数,即parser.add_argument("dog_name")
no?
是的,subparser 是要走的路。 subparsers 参数实际上是一个带有“选择”的位置(不是像你那样标记的参数),并且对于每个选择,一个解析器都有自己的一组参数(是否需要)。
如果你坚持使用'--create',你需要在解析后测试其他参数。
【参考方案1】:
看起来这可能使用子解析器,但您也可以尝试使用 click。在我的系统上运行的示例:
#!/usr/bin/env python3
import click
@click.group('parent')
def parent():
pass
@parent.group('create')
def create():
pass
@create.command()
@click.argument('name')
@click.argument('breed')
def dog(name, breed):
print(f'Dog: name: breed')
@create.command()
@click.argument('name')
def cat(name):
print(f'Cat: name')
@create.command()
@click.argument('breed')
@click.argument('tank')
def fish(breed, tank):
print(f'Fish of breed in tank')
if __name__ == '__main__':
parent()
运行时:
$ ./click_test.py --help
Usage: click_test.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create
和
$ ./click_test.py create --help
Usage: click_test.py create [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
cat
dog
fish
然后再往下
$ ./click_test.py create dog
Usage: click_test.py create dog [OPTIONS] NAME BREED
Try "click_test.py create dog --help" for help.
Error: Missing argument "NAME".
$ ./click_test.py create dog Fido Labrador
Dog: Fido: Labrador
实际上我之前对点击并没有那么感兴趣——我认为对于我想要的一些复杂案例来说它太有限了——但它实际上对于这个案例来说非常好。
【讨论】:
我可以支持 Click 的案例。我已经在生产环境中使用过它几次,并且是一个非常可靠的解决方案。 感谢您的解决方案!我确实尝试过使用 Click,但实际上为 cli 使用了一些不同的模式,并且能够提出适合我需要的东西。我会用我所做的更新我的帖子。【参考方案2】:尝试传递用引号括起来的多个参数列表,例如:
--create dog "DOG_NAME DOG_BREED"
你也可以用逗号分隔参数
--create dog DOG_NAME,DOG_BREED
使用split()
获取参数列表。
【讨论】:
感谢您的回复。我想我是在问如何根据已经存在的参数来获得不同的必需参数。即 root 命令是相同的 - 在本例中为--create
- 但根据您选择的选项,将有额外的必需参数。
我认为你必须在你的程序逻辑中实现它。为什么不直接调用--create dog
或--create cat
并为每个调用适当的逻辑呢?
我可以这样做,但如果可能的话,我想这样做。即使没有其他原因,也只是为了学习。
恐怕 Argparse 无法帮助您实现这一目标。我很确定除了将算法放入代码中之外别无他法。创建一个子解析器是一个很好的开始。以上是关于Argparse:具有可变参数的选项的可选参数的主要内容,如果未能解决你的问题,请参考以下文章