Use Python click command to invoke a class method with variadic arguments(使用Python单击命令调用带有可变参数的类方法)
                            本文介绍了使用Python单击命令调用带有可变参数的类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
                        
                        问题描述
我有一个使用以前未知数量的参数进行初始化的类,我希望使用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()
我希望在将n个参数传递给我的Foo()类之后能够运行click命令,这样我就可以初始化它并将其log()方法作为CLI命令运行,但是输出是:
错误:缺少命令
推荐答案
我不完全确定您尝试做的事情是否是解决此问题的最佳方法。我认为将变量参数放在命令后面会更符合逻辑,而且肯定更符合单击的工作方式。但是,您可以使用以下命令执行您想要的操作:
自定义类:
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 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(cls=CommandAfterArgs)
@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()
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.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> arg1 arg2 log
arguments:  ('arg1', 'arg2')
self.args: ('arg1', 'arg2')
-----------
> log --help
arguments:  ()
Usage: test.py log [OPTIONS]
Options:
  --help  Show this message and exit.
-----------
> --help
Usage: test.py [OPTIONS] [MYARGS]... COMMAND [ARGS]...
Options:
  --help  Show this message and exit.
Commands:
  log
                        这篇关于使用Python单击命令调用带有可变参数的类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
				 沃梦达教程
				
			本文标题为:使用Python单击命令调用带有可变参数的类方法
				
        
 
            
        
             猜你喜欢
        
	     - 如何在 python3 中将 OrderedDict 转换为常规字典 2022-01-01
 - padding='same' 转换为 PyTorch padding=# 2022-01-01
 - 沿轴计算直方图 2022-01-01
 - pytorch 中的自适应池是如何工作的? 2022-07-12
 - 分析异常:路径不存在:dbfs:/databricks/python/lib/python3.7/site-packages/sampleFolder/data; 2022-01-01
 - 如何将一个类的函数分成多个文件? 2022-01-01
 - python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令 2022-01-01
 - 使用Heroku上托管的Selenium登录Instagram时,找不到元素';用户名'; 2022-01-01
 - 如何在 Python 的元组列表中对每个元组中的第一个值求和? 2022-01-01
 - python-m http.server 443--使用SSL? 2022-01-01
 
				
				
				
				