代码之家  ›  专栏  ›  技术社区  ›  Håkon Hægland

为click.options()创建包装装饰器

  •  0
  • Håkon Hægland  · 技术社区  · 1 年前

    我正在尝试为click decorator创建一个包装器decorator @click.options('--foo', required=True) :

    import click
    
    def foo_option(func):
        orig_decorator = click.option('--foo', required=True)(func)
        def decorator(*args, **kwargs):
            orig_decorator(*args, **kwargs)
        return decorator
    
    @click.command()
    @foo_option
    def bar1(foo: str) -> None:
        print(f"bar1: {foo}")
    
    if __name__ == '__main__':
        bar1()
    

    这不起作用。当我像这样跑步时 script.py --foo=1 我得到错误:

    Usage: script.py [OPTIONS]
    Try 'script.py --help' for help.
    
    Error: No such option: --foo
    

    预期输出应为:

    bar1: 1
    

    我错过了什么? 看见 Refactor @click.option() arguments 以获取背景信息。

    1 回复  |  直到 1 年前
        1
  •  2
  •   Anis Rafid    1 年前

    问题在于如何构造装饰器。在这种情况下,您正在绕过click.options,这是不必要的。当您创建一个装饰器来包装另一个装饰程序(如click.option)时,您应该考虑装饰器是自下而上工作的。这是更新后的代码:

    import click
    
    
    def foo_option(func):
        return click.option('--foo', required=True)(func)
    
    
    @click.command()
    @foo_option
    def bar1(foo: str) -> None:
        print(f"bar1: {foo}")
    
    
    if __name__ == '__main__':
        bar1()
    

    当您运行脚本时,您将获得预期的输出。