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

如何使用装饰器检查类属性的初始化?

问题修复:类初始化方法的装饰器参数检查错误

错误根源

你的代码存在三个核心问题:

  1. __init__方法缺少self参数:类的实例方法必须以self作为第一个参数,否则无法绑定到实例对象。
  2. 装饰器使用方式错误:你定义的check是带参数的装饰器工厂,直接用@check装饰时,Python会把__init__函数传给check的data参数,完全偏离了你要检查初始化参数的需求。
  3. 装饰器逻辑错位:原装饰器检查的是装饰器工厂接收的固定值,而非实例化时传入的data参数。

基础修复版本

如果你只需要检查__init__的data参数是否在指定列表里,用普通装饰器即可:

def check(func):
    def wrapper(self, data, *args, **kwargs):
        if data not in ["toto", "tata"]:
            raise ValueError("Wrong argument")
        return func(self, data, *args, **kwargs)
    return wrapper

class Foo:
    @check
    def __init__(self, data):
        self.data = data

# 测试用例
Foo("toto")  # 正常运行
# Foo("t")    # 抛出 ValueError: Wrong argument

通用可配置版本

如果需要让装饰器支持检查不同参数、自定义允许值,可以改成带参数的装饰器工厂:

def check_param(param_name, allowed_values):
    def decorator(func):
        def wrapper(self, *args, **kwargs):
            # 优先获取关键字参数,再匹配位置参数
            if param_name in kwargs:
                value = kwargs[param_name]
            else:
                # 找到参数在函数签名中的位置(排除self)
                param_idx = func.__code__.co_varnames.index(param_name) - 1
                if param_idx >= len(args):
                    raise TypeError(f"Missing required parameter: {param_name}")
                value = args[param_idx]
            
            if value not in allowed_values:
                raise ValueError(f"Invalid {param_name}: {value}. Allowed values: {allowed_values}")
            return func(self, *args, **kwargs)
        return wrapper
    return decorator

class Foo:
    @check_param(param_name="data", allowed_values=["toto", "tata"])
    def __init__(self, data):
        self.data = data

# 测试用例
Foo(data="tata")  # 正常运行
# Foo(data="t")    # 抛出 ValueError: Invalid data: t. Allowed values: ['toto', 'tata']

原错误的详细解释

当你用@check装饰__init__时,Python实际执行的是:

__init__ = check(__init__)

此时check的data参数接收的是__init__函数,返回decorator函数。当你实例化Foo(data="t")时,Python会调用decorator(data="t"),但decorator只接受一个参数(被装饰的函数),因此触发TypeError: decorator() got an unexpected keyword argument 'data'。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:10:29