我正在将开源项目的 CLI从an解析传输到click。当前,该库允许使用以下CLI使用模式
manim file.py Scene1 Scene2 -p -ql但也适用于子命令(有些具有自己的子命令),如下所示:
manim plugins --list
manim cfg write --level cwd
... and more.因此,manim关键字既是一种访问子命令的方式,更重要的是,它本身具有一个位置arg ( python文件)。在arg解析中,确定manim关键字后面的文本是子命令还是位置arg是读取sys.argv[2]并确定它是否匹配可用的子命令的问题,否则就是一个位置参数。结果是添加了大量的子命令和大量样板代码.因此,转换为单击;然而,这种特殊的使用模式似乎并没有出现在点击框中。
换句话说,以下代码:
@click.group()
@click.argument('file')
def main(file):
print('main',file)
@main.command()
@click.option('--opt')
def subcommand1(opt):
print("sub1",opt)提出两个问题:
main组的位置参数才能运行任何子命令(即main file.py subcommand1而不是main subcommand1)main file.py,就不可能执行subommand1 )。经过进一步研究,我使用click Group参数invoke_without_command解决了第二个问题
@click.group(invoke_without_command=True)
@click.argument('file')
def main(file):
print('main',file)
@main.command()
@click.option('--opt')
def subcommand1(opt):
print("sub1",opt)但我仍然面临第一点的问题--选择不使用位置arg,而是调用子命令的一般能力。Stephen回答的这个StackOverflow文章似乎是相关的;但是,它只适用于帮助选项,而不是更通用的参数和选项的用例。
如何允许任意嵌套子命令(如Group ),但仍然提供像带有位置参数的@click.command()一样执行该组的功能?如果这不是一个推荐的模式,你会推荐什么呢?
发布于 2021-01-26 18:38:21
在对这个主题进行更多的研究时,我遇到了一个stackoverflow文章,它导致了这个自定义组的创建:
import click
from click.decorators import pass_context
class SkipArg(click.Group):
def parse_args(self, ctx, args):
if args[0] in self.commands:
if len(args) == 1 or args[1] not in self.commands:
# This condition needs updating for multiple positional arguments
args.insert(0, '')
super(SkipArg, self).parse_args(ctx, args)
@click.group(cls=SkipArg, invoke_without_command=True)
@click.argument('file')
@pass_context
def main(ctx, file):
print('main',ctx,file)
@main.command()
@click.option('--opt')
def subcommand1(opt):
print("sub1",opt)此代码符合使用click命令具有位置参数的命令与更多子命令嵌套的条件。在我使用click的情况下,必须更新SkipArg的逻辑,以获取多个位置参数,但作为演示就足够了。
如何达到标准:
main组作为命令运行,因为它使用invoke_without_command是可执行的。''插入到参数列表的前面。这是一个硬编码逻辑,当zeroth参数与一个子命令匹配时,它为文件位置参数应用空填充文本。https://stackoverflow.com/questions/65789839
复制相似问题