Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 单击:自定义";“缺少论点”;通过重写UsageError';s显示功能_Python_Command Line Interface_Command Line Arguments_Python Click - Fatal编程技术网

Python 单击:自定义";“缺少论点”;通过重写UsageError';s显示功能

Python 单击:自定义";“缺少论点”;通过重写UsageError';s显示功能,python,command-line-interface,command-line-arguments,python-click,Python,Command Line Interface,Command Line Arguments,Python Click,我目前正在尝试自定义错误处理,当使用Click发出命令时,没有提供所需的参数。 根据这一点,可以通过覆盖click.exceptions.UsageError的show功能来完成。 然而,我试图在那里修改提供的解决方案,但我无法让它工作 在我的例子中,我希望能够获得应该执行的命令(但由于缺少参数而失败),并且根据输入的命令,我希望进一步处理。 我的示例代码如下所示: @click.group(cls=MyGroup) def myapp(): pass @myapp.command()

我目前正在尝试自定义错误处理,当使用Click发出命令时,没有提供所需的参数。 根据这一点,可以通过覆盖
click.exceptions.UsageError
show
功能来完成。 然而,我试图在那里修改提供的解决方案,但我无法让它工作

在我的例子中,我希望能够获得应该执行的命令(但由于缺少参数而失败),并且根据输入的命令,我希望进一步处理。 我的示例代码如下所示:

@click.group(cls=MyGroup)
def myapp():
    pass

@myapp.command()
@click.argument('myarg',type=str)
def mycommand(myarg: str) -> None:
    do_stuff(myarg)
class myGroup(click.Group):
"""
Customize help order and get_command
https://stackoverflow.com/a/47984810/713980
"""

def __init__(self, *args, **kwargs):
    self.help_priorities = {}
    super(myGroup, self).__init__(*args, **kwargs)

def get_help(self, ctx):
    self.list_commands = self.list_commands_for_help
    return super(myGroup, self).get_help(ctx)

def list_commands_for_help(self, ctx):
    """reorder the list of commands when listing the help"""
    commands = super(myGroup, self).list_commands(ctx)
    return (c[1] for c in sorted((self.help_priorities.get(command, 1000), command) for command in commands))

def command(self, *args, **kwargs):
    """Behaves the same as `click.Group.command()` except capture
    a priority for listing command names in help.
    """
    help_priority = kwargs.pop('help_priority', 1000)
    help_priorities = self.help_priorities

    def decorator(f):
        cmd = super(myGroup, self).command(*args, **kwargs)(f)
        help_priorities[cmd.name] = help_priority
        return cmd
    return decorator

def get_command(self, ctx, cmd_name):
    rv = click.Group.get_command(self, ctx, cmd_name)
    if rv is not None:
        return rv
    sim_commands = most_sim_com(cmd_name, COMMANDS)

    matches = [cmd for cmd in self.list_commands(ctx) if cmd in sim_commands]
    if not matches:
        ctx.fail(click.style('Unknown command and no similar command was found!', fg='red'))
    elif len(matches) == 1:
        click.echo(click.style(f'Unknown command! Will use best match {matches[0]}.', fg='red'))
        return click.Group.get_command(self, ctx, matches[0])
    ctx.fail(click.style(f'Unknown command. Most similar commands were {", ".join(sorted(matches))}', fg='red'))
因此,如果该命令类似于
myapp mycommand
,并且遗漏了所需的参数,我希望单独处理它。 我搜索了一段时间,但无法找出如何获取命令(我尝试传递上下文,但据我所知,
UsageError
在初始化时未传递上下文)

如果有任何提示或想法,我将不胜感激

编辑:
myGroup
的实现如下所示:

@click.group(cls=MyGroup)
def myapp():
    pass

@myapp.command()
@click.argument('myarg',type=str)
def mycommand(myarg: str) -> None:
    do_stuff(myarg)
class myGroup(click.Group):
"""
Customize help order and get_command
https://stackoverflow.com/a/47984810/713980
"""

def __init__(self, *args, **kwargs):
    self.help_priorities = {}
    super(myGroup, self).__init__(*args, **kwargs)

def get_help(self, ctx):
    self.list_commands = self.list_commands_for_help
    return super(myGroup, self).get_help(ctx)

def list_commands_for_help(self, ctx):
    """reorder the list of commands when listing the help"""
    commands = super(myGroup, self).list_commands(ctx)
    return (c[1] for c in sorted((self.help_priorities.get(command, 1000), command) for command in commands))

def command(self, *args, **kwargs):
    """Behaves the same as `click.Group.command()` except capture
    a priority for listing command names in help.
    """
    help_priority = kwargs.pop('help_priority', 1000)
    help_priorities = self.help_priorities

    def decorator(f):
        cmd = super(myGroup, self).command(*args, **kwargs)(f)
        help_priorities[cmd.name] = help_priority
        return cmd
    return decorator

def get_command(self, ctx, cmd_name):
    rv = click.Group.get_command(self, ctx, cmd_name)
    if rv is not None:
        return rv
    sim_commands = most_sim_com(cmd_name, COMMANDS)

    matches = [cmd for cmd in self.list_commands(ctx) if cmd in sim_commands]
    if not matches:
        ctx.fail(click.style('Unknown command and no similar command was found!', fg='red'))
    elif len(matches) == 1:
        click.echo(click.style(f'Unknown command! Will use best match {matches[0]}.', fg='red'))
        return click.Group.get_command(self, ctx, matches[0])
    ctx.fail(click.style(f'Unknown command. Most similar commands were {", ".join(sorted(matches))}', fg='red'))

这是一个初稿,也是我能想到的最幼稚的解决方案,所以如果不能完全解决您的问题,它可能会改变它。将代码更改为类似这样的内容会有帮助吗

@click.group(cls=MyGroup)
def myapp():
通过
@myapp.command()
@click.argument('myarg',type=str,required=False)
def mycommand(myarg:str=None)->None:
验证_my_命令(myarg)#这是进行自定义逻辑和错误消息处理的地方
这样做的好处是,它是明确的,并且与
Click
的建议方法保持一致。但是,如果你想为每个命令这样做,我们可以考虑更复杂的方法


让我知道你的想法

你好。你能发布你的
MyGroup
实现吗?嘿;),我在上面编辑了我的帖子。所以,为了澄清,如果
myarg
没有传递到命令调用中,您希望能够有一条自定义错误消息?是的,但是另外,我希望能够知道调用了哪个命令,以便根据该命令执行一系列其他操作,不错的解决方案没有考虑设置为
False
,这非常直观。我想对于我的其他命令我也会这样做,避免实现太复杂的东西。出于好奇:更复杂的方法是什么样的?我真的不能告诉你。我想象着这样的事情:要么装饰一个click命令,为您进行验证,这听起来是可行的。或者,滚动您自己的
命令实现
,但每当单击API发生变化时(不是经常发生变化,但需要注意)。创建我自己的decorator听起来很有趣。但无论如何,再次感谢你;)