在点击命令之上装饰
decorate on top of a click command
我正在尝试装饰一个已经被 @click
装饰并从命令行调用的函数。
将输入大写的正常装饰可能如下所示:
standard_decoration.py
def capitalise_input(f):
def wrapper(*args):
args = (args[0].upper(),)
f(*args)
return wrapper
@capitalise_input
def print_something(name):
print(name)
if __name__ == '__main__':
print_something("Hello")
然后从命令行:
$ python standard_decoration.py
HELLO
click documentation 中的第一个示例如下所示:
hello.py
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
hello()
当从命令行 运行 时:
$ python hello.py --count=3
Your name: John
Hello John!
Hello John!
Hello John!
应用装饰器的正确方法是什么,该装饰器会修改此点击装饰函数的输入,例如像上面那样将其设为大写?
一旦一个函数被点击修饰,是否可以说它所有的位置参数都被转换为关键字参数?它似乎将 '--count'
之类的东西与参数函数中的字符串匹配,然后装饰函数中的顺序似乎不再重要。
点击似乎传递了关键字参数。这应该工作。我认为它需要成为第一个装饰器,即在所有点击方法完成后调用它。
def capitalise_input(f):
def wrapper(**kwargs):
kwargs['name'] = kwargs['name'].upper()
f(**kwargs)
return wrapper
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
@capitalise_input
def hello(count, name):
....
您也可以尝试类似这样的方法来具体说明要大写的参数:
def capitalise_input(key):
def decorator(f):
def wrapper(**kwargs):
kwargs[key] = kwargs[key].upper()
f(**kwargs)
return wrapper
return decorator
@capitalise_input('name')
def hello(count, name):
Harvey 的回答不适用于命令组。实际上,这会将 'hello' 命令替换为 'wrapper',这不是我们想要的。而是尝试类似的东西:
from functools import wraps
def test_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
kwargs['name'] = kwargs['name'].upper()
return f(*args, **kwargs)
return wrapper
关于单击命令组 - 我们需要考虑文档中的内容 - https://click.palletsprojects.com/en/7.x/commands/#decorating-commands
所以最后一个像这样的简单装饰器:
def sample_decorator(f):
def run(*args, **kwargs):
return f(*args, param="yea", **kwargs)
return run
需要转换为与点击一起使用:
from functools import update_wrapper
def sample_decorator(f):
@click.pass_context
def run(ctx, *args, **kwargs):
return ctx.invoke(f, *args, param="yea", **kwargs)
return update_wrapper(run, f)
(文档建议使用 ctx.invoke(f, ctx.obj,
,但这导致了 'duplicite arguments' 的错误。)
我正在尝试装饰一个已经被 @click
装饰并从命令行调用的函数。
将输入大写的正常装饰可能如下所示:
standard_decoration.py
def capitalise_input(f):
def wrapper(*args):
args = (args[0].upper(),)
f(*args)
return wrapper
@capitalise_input
def print_something(name):
print(name)
if __name__ == '__main__':
print_something("Hello")
然后从命令行:
$ python standard_decoration.py
HELLO
click documentation 中的第一个示例如下所示:
hello.py
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo('Hello %s!' % name)
if __name__ == '__main__':
hello()
当从命令行 运行 时:
$ python hello.py --count=3
Your name: John
Hello John!
Hello John!
Hello John!
应用装饰器的正确方法是什么,该装饰器会修改此点击装饰函数的输入,例如像上面那样将其设为大写?
一旦一个函数被点击修饰,是否可以说它所有的位置参数都被转换为关键字参数?它似乎将
'--count'
之类的东西与参数函数中的字符串匹配,然后装饰函数中的顺序似乎不再重要。
点击似乎传递了关键字参数。这应该工作。我认为它需要成为第一个装饰器,即在所有点击方法完成后调用它。
def capitalise_input(f):
def wrapper(**kwargs):
kwargs['name'] = kwargs['name'].upper()
f(**kwargs)
return wrapper
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
help='The person to greet.')
@capitalise_input
def hello(count, name):
....
您也可以尝试类似这样的方法来具体说明要大写的参数:
def capitalise_input(key):
def decorator(f):
def wrapper(**kwargs):
kwargs[key] = kwargs[key].upper()
f(**kwargs)
return wrapper
return decorator
@capitalise_input('name')
def hello(count, name):
Harvey 的回答不适用于命令组。实际上,这会将 'hello' 命令替换为 'wrapper',这不是我们想要的。而是尝试类似的东西:
from functools import wraps
def test_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
kwargs['name'] = kwargs['name'].upper()
return f(*args, **kwargs)
return wrapper
关于单击命令组 - 我们需要考虑文档中的内容 - https://click.palletsprojects.com/en/7.x/commands/#decorating-commands
所以最后一个像这样的简单装饰器:
def sample_decorator(f):
def run(*args, **kwargs):
return f(*args, param="yea", **kwargs)
return run
需要转换为与点击一起使用:
from functools import update_wrapper
def sample_decorator(f):
@click.pass_context
def run(ctx, *args, **kwargs):
return ctx.invoke(f, *args, param="yea", **kwargs)
return update_wrapper(run, f)
(文档建议使用 ctx.invoke(f, ctx.obj,
,但这导致了 'duplicite arguments' 的错误。)