为什么点击add_command不起作用?

问题描述 投票:0回答:1

python script.py
运行以下代码不会执行任何操作。我预计至少会打印
click.echo
声明。似乎对
first_command
的调用不起作用。知道为什么吗?

    import click
    
    def multiple_input_option(**option_kwargs):
        def decorator(func):
            def _callback(ctx, param, value):
                ctx.obj['multiple_options'] = value
    
            help_text = 'some options to get from user'
    
            keyword_arguments = {
                'help': help_text,
                'callback': _callback,
                'expose_value': False,
                'multiple': True,
            }
            keyword_arguments.update(**option_kwargs)
    
            return click.option('--multiple-options', '-e', **keyword_arguments)(func)
    
        return decorator
    
    @click.command()
    @multiple_input_option()
    def first_command(ctx):
        click.echo('> hello...first_command')
        command_param_data = ctx.obj.keys()
    
        click.echo(json.dumps(command_param_data, indent=2))
    
    @click.group()
    def hello_world(ctx):
        """
        Your plugin description here
        """
        ctx.ensure_object(dict)
     
    # This is how we add more sub-commands
    hello_world.add_command(first_command)
python python-click
1个回答
3
投票

我想出了以下解决方案。

import click
#(1) import json, other wise json.dump will not work
import json

def multiple_input_option(**option_kwargs):
    def decorator(func):
        def _callback(ctx, param, value):
          ctx.obj['multiple_options'] = value

        help_text = 'some options to get from user'

        keyword_arguments = {
            'help': help_text,
            'callback': _callback,
            'expose_value': False,
            'multiple': True,
        }
        keyword_arguments.update(**option_kwargs)

        return click.option('--multiple-options', '-e', **keyword_arguments)(func)

    return decorator

@click.command()
@multiple_input_option()
#(2) pass context here
@click.pass_context
def first_command(ctx):
    click.echo('> hello...first_command')
    command_param_data = ctx.obj.keys()   
    click.echo(json.dumps(command_param_data, indent=2))

@click.group()
#(3) pass context here
@click.pass_context
def hello_world(ctx):
    """
    Your plugin description here
    """
    ctx.ensure_object(dict)

# This is how we add more sub-commands
hello_world.add_command(first_command)

#(4) make a call in the main function
if __name__ == '__main__':
  hello_world()

输出如下:

我必须执行以下操作才能使其正常工作:

(1)导入json模块,这样就可以使用json.dump了

import json

(2)/(3) 由于 hello_worldfirst_command 需要上下文,因此您必须通过

传递它
click.pass_context

根据Click文档这里

[w]每当执行 Click 命令时,都会创建一个 Context 对象,该对象保存此特定调用的状态。它会记住解析的参数、创建它的命令、在函数结束时需要清理哪些资源等等。它还可以选择保存应用程序定义的对象。

如上所述,Context 是“Context”类的对象(请参阅 Click API here 了解更多信息)。你在hello_world和first_command中使用的参数“ctx”就是这样一个对象。在 hello_world 中,您调用函数“ensure_object”,它是“Context”类的函数。由于您正在使用上下文对象,因此您必须确保将其传递给您的命令,这是由

完成的
click.pass_context

(4) 最后我添加了一个 main 函数,用于调用命令

if __name__ == '__main__':
    hello_world()

最后一句话

json.dump
。我假设您使用的是 python 2.x,在这种情况下调用就可以了。对于 python 3.x,调用应该如下所示:

click.echo(json.dumps(list(command_param_data), indent=2))
© www.soinside.com 2019 - 2024. All rights reserved.