Ser*_*gey 4 python python-click
我正在尝试用Click完成CLI解析方面不是很标准的事情,并且只能部分工作:
样品:
import click
@click.group()
@click.argument('hostname', required=False)
@click.pass_context
def cli(ctx, hostname=None):
""""""
ctx.obj = hostname
click.echo("cli: hostname={}".format(hostname))
@cli.command()
@click.pass_obj
def check(hostname):
click.echo("check: hostname={}".format(hostname))
@cli.command()
@click.pass_obj
def show(hostname):
click.echo("check: hostname={}".format(hostname))
if __name__ == '__main__':
cli()
Run Code Online (Sandbox Code Playgroud)
具有主机名的部分起作用:
> pipenv run python cli.py localhost check
cli: hostname=localhost
check: hostname=localhost
> pipenv run python cli.py localhost show
cli: hostname=localhost
check: hostname=localhost
Run Code Online (Sandbox Code Playgroud)
但是没有主机名的那部分却没有:
> pipenv run python cli.py show
Usage: cli.py [OPTIONS] [HOSTNAME] COMMAND [ARGS]...
Error: Missing command.
Run Code Online (Sandbox Code Playgroud)
有人对我应该开始研究的方向有所了解吗?
这可以通过像这样遍历click.Group参数解析器来完成:
自订类别:
class MyGroup(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:
args.insert(0, '')
super(MyGroup, self).parse_args(ctx, args)
Run Code Online (Sandbox Code Playgroud)
使用自定义类:
然后使用自定义组,将其作为cls参数传递给group装饰器,如下所示:
@click.group(cls=MyGroup)
@click.argument('hostname', required=False)
@click.pass_context
def cli(ctx, hostname=None):
....
Run Code Online (Sandbox Code Playgroud)
怎么样?
之所以click可行,是因为它是一个设计良好的OO框架。该@click.group()装饰通常实例化一个click.Group对象,但允许与被骑过这种行为cls的参数。因此,click.Group在我们自己的类中继承所需的方法是相对容易的事情。
在这种情况下,我们遇到了麻烦click.Group.parse_args(),如果第一个参数与命令匹配,而第二个参数与命令不匹配,则我们插入一个空字符串作为第一个参数。这会将所有内容放回解析器期望的位置。
| 归档时间: |
|
| 查看次数: |
6971 次 |
| 最近记录: |