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

如何使用带参数的装饰器类装饰实例方法?参数验证场景报错求解

类装饰器处理实例方法的标准解决方案

你的问题核心是类装饰器在处理实例方法时,没有正确绑定self参数,导致原方法调用时参数不匹配。以下是修正后的实现,以及类装饰器处理实例方法的标准模式说明:

错误原因分析

当用@MyDecorator(str, float)装饰__init__方法时,装饰器返回的wrapper_func被作为类属性存储,但它并非绑定方法。创建实例时Python不会自动传入self参数,导致调用原__init__时参数缺失,触发TypeError。

修正后的装饰器实现

import functools

class MyDecorator:
    """
    用于检查函数/方法参数类型的类装饰器
    """
    def __init__(self, *args):
        self.types = args
        self.wrapper = None

    def __call__(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # 确定参数检查的起始索引:实例方法跳过第一个self参数
            start_idx = 0
            # 简单判断是否为实例方法:第一个参数是类实例且包含原方法名
            if args and hasattr(args[0], func.__name__):
                start_idx = 1

            # 遍历检查指定参数的类型
            for i in range(len(self.types)):
                arg_idx = start_idx + i
                if arg_idx >= len(args):
                    print(f"警告:缺失第{i+1}个预期参数")
                    break
                arg = args[arg_idx]
                expected_type = self.types[i]
                if not isinstance(arg, expected_type):
                    print(f"警告:第{arg_idx+1}个参数类型错误,预期{expected_type.__name__},实际{type(arg).__name__}: {arg}")
            
            return func(*args, **kwargs)
        
        self.wrapper = wrapper
        return wrapper

    def __get__(self, instance, owner):
        # 实现描述符协议,返回绑定实例的包装函数
        if instance is None:
            return self
        return functools.partial(self.wrapper, instance)

测试验证

普通函数场景

@MyDecorator(int, float)
def addition(a, b):
    return a + b

addition(4, 5)       # 输出警告:第2个参数类型错误,预期float,实际int:5
addition(4, 5.5)     # 正常执行,返回9.5

实例方法场景

class Car:
    @MyDecorator(str, float)
    def __init__(self, color, price):
        self.color = color
        self.price = price

my_car = Car('Green', 120.0)  # 正常执行
my_car2 = Car('Red', 120)     # 输出警告:第2个参数类型错误,预期float,实际int:120
my_car3 = Car(123, 120.0)     # 输出警告:第1个参数类型错误,预期str,实际int:123

类装饰器处理实例方法的标准模式要点

  1. 实现描述符协议:通过__get__方法,当装饰器作为类属性被访问时,返回绑定了实例的partial函数,确保实例方法调用时自动传入self参数。
  2. 保留函数元信息:使用functools.wraps装饰包装函数,保留原函数的名称、文档字符串等元信息,避免破坏方法的正常绑定行为。
  3. 区分普通函数与实例方法:根据参数特征判断是否为实例方法,调整类型检查的起始索引,跳过不需要检查的self参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:09:56