使用 Python click 命令调用带有可变参数的类方法

我有一个使用以前未知数量的参数初始化的类,我希望它使用 Python 的click包在 CLI 上完成。我的问题是我无法初始化它并运行click命令:


$ python mycode.py arg1 arg2 ... argN click_command

设置定义数量的参数,如nargs=5,解决了缺少命令的问题,但我有义务在我的命令之前输入 5 个参数。对于像nargs=-1, 之类的可变参数,click不能识别click_command为命令。


如何输入 n 个参数,然后使用click?


import click


class Foo(object):

    def __init__(self, *args):

        self.args = args


    def log(self):

        print('self.args:', self.args)


pass_foo = click.make_pass_decorator(Foo)


@click.group()

@click.argument('myargs', nargs=-1)

@click.pass_context

def main(ctx, myargs):

    ctx.obj = Foo(myargs)

    print("arguments: ", myargs)


@main.command()

@pass_foo

def log(foo):

    foo.log()


main()

我希望能够click在将 n-many args 传递给我的Foo()类后运行命令,因此我可以初始化它并将其log()方法作为 CLI 命令运行,但输出是:


错误:缺少命令


潇湘沐
浏览 278回答 1
1回答

一只萌萌小番薯

我不完全确定您正在尝试做的是解决此问题的最佳方法。我认为在命令之后放置可变参数会更合乎逻辑,并且肯定会更符合 click 的工作方式。但是,你可以用这个做你想做的事情:自定义类:class CommandAfterArgs(click.Group):    def parse_args(self, ctx, args):        parsed_args = super(CommandAfterArgs, self).parse_args(ctx, args)        possible_command = ctx.params['myargs'][-1]        if possible_command in self.commands:            ctx.protected_args = [possible_command]            ctx.params['myargs'] = ctx.params['myargs'][:-1]        elif possible_command in ('-h', '--help'):            if len(ctx.params['myargs']) > 1 and \                    ctx.params['myargs'][-2] in self.commands:                ctx.protected_args = [ctx.params['myargs'][-2]]                parsed_args = ['--help']                ctx.params['myargs'] = ctx.params['myargs'][:-2]                ctx.args = [possible_command]        return parsed_args使用自定义类:然后要使用自定义类,将它作为cls参数传递给组装饰器,如:@click.group(cls=CommandAfterArgs)@click.argument('myargs', nargs=-1)def main(myargs):    ...测试代码:import clickclass Foo(object):    def __init__(self, *args):        self.args = args    def log(self):        print('self.args:', self.args)pass_foo = click.make_pass_decorator(Foo)@click.group(cls=CommandAfterArgs)@click.argument('myargs', nargs=-1)@click.pass_contextdef main(ctx, myargs):    ctx.obj = Foo(*myargs)    print("arguments: ", myargs)@main.command()@pass_foodef log(foo):    foo.log()if __name__ == "__main__":    commands = (        'arg1 arg2 log',        'log --help',        '--help',    )    import sys, time    time.sleep(1)    print('Click Version: {}'.format(click.__version__))    print('Python Version: {}'.format(sys.version))    for cmd in commands:        try:            time.sleep(0.1)            print('-----------')            print('> ' + cmd)            time.sleep(0.1)            main(cmd.split())        except BaseException as exc:            if str(exc) != '0' and \                    not isinstance(exc, (click.ClickException, SystemExit)):                raise结果:Click Version: 6.7Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]-----------> arg1 arg2 logarguments:  ('arg1', 'arg2')self.args: ('arg1', 'arg2')-----------> log --helparguments:  ()Usage: test.py log [OPTIONS]Options:  --help  Show this message and exit.-----------> --helpUsage: test.py [OPTIONS] [MYARGS]... COMMAND [ARGS]...Options:  --help  Show this message and exit.Commands:  log
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python