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

Python描述符搭配装饰器做类型检查报__get__参数错误如何修复?

报错原因

Python描述符协议要求__get__方法必须接收3个参数,签名为__get__(self, instance, owner),各参数含义如下:

  • self:描述符类自身的实例
  • instance:访问描述符属性的类实例,通过类直接访问属性时该值为None
  • owner:描述符属性所属的类
    你当前只定义了2个参数,Python调用时自动传入3个参数,就会触发参数数量不匹配的报错。

修复方法

补全__get__方法的第三个参数即可,用不到的话可以直接用占位符命名。另外你当前的实现把属性值存在描述符实例上,会导致所有MyClass的实例共享同一个值,建议改为把值存在对应类实例上,避免实例间数据冲突。

修复后的完整代码如下:

# 描述符定义
class PositiveNumber:
    def __get__(self, obj, owner):
        # 从类实例上取值,避免多实例共享
        return obj._value

    def __set__(self, obj, value):
        if not isinstance(value, (int, float)):
            raise TypeError('value must be a number')
        if value < 0:
            raise ValueError('Value cannot be negative.')
        # 把值存在当前类实例上
        obj._value = value

# 装饰器定义
def positive_number(attr):
    def decorator(cls):
        setattr(cls, attr, PositiveNumber())
        return cls
    return decorator

# 实际执行类型校验的类
@positive_number('number')
class MyClass(object):
    def __init__(self, value):
        self.number = value


def main():
    a = MyClass(3)
    print(a.number)


if __name__ == '__main__':
    main()

如果你不需要支持多实例,只是要解决当前报错,只需要把__get__的签名改成def __get__(self, obj, _):即可,其他代码不用改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:06:03