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

attrs包是否存在与on_setattr功能对等的on_getattr相关特性?

attrs 本身提供了原生的自定义 getter 逻辑支持,不需要通过重写魔法方法或者额外定义异名属性的方式实现,下面是两种最常用的落地方案:

方案1:使用 attrs 22.2+ 内置的 getter 参数(官方推荐)

这个参数就是专门为属性读取时添加自定义逻辑设计的,不需要修改原有属性命名,所有 attrs 原生特性(包括 on_setattr、字段校验、__repr__、序列化能力等)都可以完全兼容,用法如下:

import attr

# 自定义getter逻辑,固定接收三个参数:类实例、字段定义对象、存储的原始值
def name_getter(instance, field, raw_value):
    return raw_value.upper()

@attr.s(kw_only=True)
class Customer:
    name = attr.ib(
        type=str, 
        on_setattr=[prevent_empty_string, other_validators_or_logics],
        # 直接指定getter函数即可
        getter=name_getter
    )

使用时直接正常读取 customer.name 就会自动触发自定义逻辑,拿到处理后的值。

方案2:私有存储字段+同名property(兼容低版本attrs)

如果你使用的 attrs 版本低于22.2,没有内置 getter 参数,可以用这种兼容性更强的方案:将实际存储值的字段设为私有属性,对外暴露同名的 property 处理读写逻辑,原有的 on_setattr 逻辑作用在私有存储字段上不会失效。

import attr

@attr.s(kw_only=True)
class Customer:
    # 私有存储字段,设置repr=False避免__repr__打印私有属性
    _name = attr.ib(
        type=str, 
        on_setattr=[prevent_empty_string, other_validators_or_logics],
        repr=False
    )

    @property
    def name(self):
        # 自定义getter逻辑
        return self._name.upper()
    
    # 如果需要支持赋值,补充setter即可,on_setattr逻辑仍会生效
    @name.setter
    def name(self, value):
        self._name = value

这种方案对外的接口和普通属性完全一致,也不会破坏 attrs 的原生特性。

不推荐方案说明

  • 额外定义异名属性(比如get_name):会导致类对外暴露两套属性接口,使用起来不直观,也不符合Python的编码习惯
  • 重写__getattribute__:会引入大量分支判断提升维护成本,同时会改变所有属性读取的默认逻辑,很容易破坏 attrs 内置的__repr__、序列化等能力,性能也会有劣化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:36:02