为click.options()创建包装装饰器时遇--foo选项无法识别问题
问题原因及修复方案
你的代码问题出在自定义装饰器的实现逻辑上:你在foo_option里手动包了一层decorator函数,但这层函数没有保留被click.option装饰后的原函数的元数据——Click正是依靠这些元数据来识别命令行选项的。当你返回这个新的decorator函数时,Click无法读取到--foo选项的注册信息,自然会报错说不存在该选项。
修复后的代码
import click def foo_option(func): # 直接返回被click.option装饰后的函数,不需要额外封装层 return click.option('--foo', required=True)(func) @click.command() @foo_option def bar1(foo: str) -> None: print(f"bar1: {foo}") if __name__ == '__main__': bar1()
运行script.py --foo=1后,就能得到期望的输出:
bar1: 1
如果后续需要扩展这个装饰器(比如添加自定义逻辑),可以用带元数据保留的标准装饰器写法:
import click from functools import wraps def foo_option(func): # 先用click.option装饰原函数 decorated_func = click.option('--foo', required=True)(func) @wraps(decorated_func) # 保留原函数的元数据,让Click能识别选项 def wrapper(*args, **kwargs): # 这里可以添加自定义前置/后置逻辑 return decorated_func(*args, **kwargs) return wrapper
这个写法既保证Click能正确识别--foo选项,也支持你在wrapper中添加额外处理逻辑。
内容的提问来源于stack exchange,提问作者Håkon Hægland
相关产品推荐
相关产品推荐

