You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在装饰器中使用被装饰方法的可选参数

如何在装饰器中获取被装饰函数的可选参数(含默认值)?

你当前的装饰器只能捕获调用时显式传入的参数,而optional_arg使用默认值时,不会出现在args或kwargs里——因为默认参数的赋值逻辑是在被装饰函数内部执行的,装饰器的wrapper拿不到这个值。要解决这个问题,我们可以借助Python的inspect模块来解析函数的参数签名,从而获取完整的参数信息(包括默认值和调用时的实际传入值)。

解决方案代码

import inspect
from typing import Callable, Any

class YourClass:
    def decorator(self, func: Callable[[Any], Any]) -> Callable[[Any, Any], Any]:
        # 获取被装饰函数的参数签名
        func_sig = inspect.signature(func)
        
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            # 绑定调用时的参数到签名,生成参数映射
            bound_args = func_sig.bind(*args, **kwargs)
            # 填充未传入参数的默认值
            bound_args.apply_defaults()
            
            # 现在可以获取所有参数的实际值(包括默认值)
            full_args = bound_args.arguments
            print("完整参数列表:", full_args)
            
            # 提取optional_arg的值
            optional_arg = full_args["optional_arg"]
            print(f"optional_arg的当前值:{optional_arg}")
            
            return func(*args, **kwargs)

        return wrapper

    @decorator
    def do_something(self, arg1: str, optional_arg="Hi") -> None:
        pass

# 测试调用
obj = YourClass()
obj.do_something("arg1")  # 输出optional_arg为默认值"Hi"
obj.do_something("arg1", optional_arg="Hello")  # 输出optional_arg为"Hello"

关键步骤说明

  1. 获取函数签名:inspect.signature(func)会解析函数的参数结构,返回一个包含所有参数信息的对象,包括每个参数的默认值、位置等。
  2. 绑定并填充参数:
    • func_sig.bind(*args, **kwargs)将调用时传入的参数与签名进行匹配,生成BoundArguments对象。
    • bound_args.apply_defaults()会自动为未传入的参数填充定义时的默认值,确保bound_args.arguments包含所有参数的实际值。
  3. 提取目标参数:直接从bound_args.arguments字典中通过键名("optional_arg")获取参数值即可,不管是默认值还是显式传入的值都能拿到。

额外说明

如果只是想单独获取某个参数的默认值(不需要调用时的实际值),可以直接从签名的参数列表中提取:

# 在decorator函数内部,获取func的签名后
optional_default = func_sig.parameters["optional_arg"].default
print(f"optional_arg的默认值:{optional_default}")

内容的提问来源于stack exchange,提问作者Zigzagoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 07:37:19