我想让它更加无缝,所以我将它与修改函数的全局范围的技巧结合起来,并提出了以下装饰器:def with_click_params(func): @functools.wraps(func) def wrapper(*args, **kwargs): g = func.__globals__ sentinel = object() ctx = click.get_current_context() oldvalues = {} for param in ctx.params: oldvalues[param] = g.get(param, sentinel) g[param] = ctx.params[param] try: return func(*args, **kwargs) finally: for param in ctx.params: if oldvalues[param] is sentinel: del g[param] else: g[param] = oldvalues[param] return wrapper你可以像这样使用它(从@dthor的答案借用示例):@with_click_paramsdef some_func(): print(f"The value of foo is: {foo}") print(f"The value of bar is: {bar}")@click.command()@click.option("--foo")@click.option("--bar")def main(foo, bar): some_func()if __name__ == "__main__": main()这是它的实际效果:$ python test2.py --foo 1 --bar "bbb"The value of foo is: 1The value of bar is: bbb注意事项:函数只能从click原始调用堆栈调用,但这是一个有意识的选择(即,您将对变量注入做出假设)。点击单元测试指南在这里应该很有用。该函数不再是线程安全的。也可以明确要注入的参数名称:def with_click_params(*params): def wrapper(func): @functools.wraps(func) def inner_wrapper(*args, **kwargs): g = func.__globals__ sentinel = object() ctx = click.get_current_context() oldvalues = {} for param in params: oldvalues[param] = g.get(param, sentinel) g[param] = ctx.params[param] try: return func(*args, **kwargs) finally: for param in params: if oldvalues[param] is sentinel: del g[param] else: g[param] = oldvalue return inner_wrapper return wrapper@with_click_params("foo")def some_func(): print(f"The value of foo is: {foo}")@click.command()@click.option("--foo")@click.option("--bar")def main(foo, bar): some_func()if __name__ == "__main__": main()