首页 > 解决方案 > 为什么单击 add_command 不起作用?

问题描述

运行以下代码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)

标签: pythonclick

解决方案


我想出了以下解决方案。

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 对象,该对象保存此特定调用的状态。它会记住已解析的参数、创建它的命令、函数结束时需要清理的资源等等。它还可以选择保存应用程序定义的对象。

如上所述,上下文是“上下文”类的对象(有关更多信息,请参见此处的 Click API )。您在 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))

推荐阅读