只读描述符通过拦截属性写入并抛出异常保障支付配置不可篡改,需在构造函数中完成校验与首次赋值,防范反序列化绕过,并配合Final类型提示与静态检查强化防御。

只读描述符是保障微任务支付配置不可篡改的底层机制,它在运行时拦截属性写入操作,比单纯命名约定或文档约束更可靠。关键不在于“禁止修改”的表象,而在于让非法赋值在第一时间触发明确异常,阻断错误传播链。
用描述符封装支付核心参数
将金额精度、结算周期、手续费率等敏感字段交由自定义描述符管理,而非普通实例属性。描述符的__set__方法直接抛出AttributeError,确保任何尝试(包括反射、setattr、字典赋值)都会失败。
- 定义一个
ReadOnlyDescriptor类,仅实现__get__和__set__,后者固定抛错 - 在支付配置类中,将
settlement_window、fee_rate等声明为该描述符的实例 - 初始化时通过
__set__完成首次赋值,后续所有写操作均被拦截
结合构造函数强制初始化校验
只读不等于无约束。描述符本身不验证值的合法性,需在构造阶段嵌入业务规则检查。例如,手续费率必须介于0.001%–0.5%,结算窗口必须是正整数天。
- 构造函数接收原始参数后,先执行范围/格式校验,再调用描述符的
__set__完成赋值 - 避免在
__init__中直接给self._attr赋值,绕过描述符控制 - 校验失败时抛出
ValueError并附带具体字段名,便于运维定位
防止反序列化绕过只读保护
JSON或pickle反序列化可能跳过__init__,直接写入__dict__,这是常见漏洞点。必须重写__setstate__或__post_init__(如用dataclass)来重建描述符管控。
- 若使用
pickle,实现__setstate__,对每个只读字段手动调用描述符__set__ - 若使用
json,在from_dict类方法中统一走构造逻辑,拒绝裸字典赋值 - 禁用
__dict__.update()式批量注入,所有外部数据必须经校验管道
配合类型提示与静态检查增强防御纵深
描述符提供运行时防护,但开发阶段就应暴露风险。用Final类型注解配合mypy,让IDE和CI提前报错。
- 为只读字段添加
Final[float]或Final[Literal["daily"]]提示 - 启用
mypy --disallow-any-expr阻止动态属性访问 - 在CI中加入
pylint检查,禁止对已标注Final的变量重新赋值

















