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

如何重写嵌套点运算符?解决__getattr__属性链识别问题

解决自定义类中属性链追踪与自定义返回值的问题

要实现你需要的功能——区分不同的属性链(比如a.b和a.b.c)并返回不同结果,核心思路是用一个「属性追踪器」来记录完整的属性访问路径,直到触发实际求值操作(比如打印、显式转换为字符串)时,再根据完整路径返回对应的值。

下面是具体的实现代码:

class AttrTracker:
    def __init__(self, path):
        self.path = path

    def __getattr__(self, name):
        # 每次访问新属性,就把属性名追加到路径中,返回新的追踪器
        return AttrTracker(self.path + [name])

    def __str__(self):
        # 根据完整的属性路径返回对应结果
        if self.path == ['b']:
            return "hello"
        elif self.path == ['b', 'c']:
            return "hi"
        # 可以继续扩展其他属性链的处理逻辑
        else:
            return f"Unsupported path: {'.'.join(self.path)}"

class A:
    def __getattr__(self, name):
        # 第一次访问属性时,初始化追踪器,路径为当前属性名
        return AttrTracker([name])

# 测试代码
a = A()
print(a.b)       # 输出"hello"
print(a.b.c)     # 输出"hi"
print(a.x.y.z)   # 输出"Unsupported path: x.y.z"

原理说明

  1. 属性追踪器的作用:AttrTracker类负责记录每次属性访问的完整路径。当你访问a.b时,A的__getattr__返回一个AttrTracker(path=['b']);当继续访问a.b.c时,这个追踪器的__getattr__会生成一个新的AttrTracker(path=['b','c']),以此类推,每一步都在累积属性路径。
  2. 延迟求值:只有当需要实际获取值的时候(比如print会调用对象的__str__方法),才根据完整的属性路径返回对应的结果。这样就能完美区分a.b和a.b.c——它们是两个不同的追踪器实例,各自保存着不同的路径。
  3. 扩展性:如果需要支持更多属性链的返回值,只需要在AttrTracker的__str__方法中添加新的判断分支即可。如果需要支持其他操作(比如属性链后调用函数,像a.b.c()),可以重写__call__方法,同样根据self.path来处理逻辑。

额外优化点

如果你希望属性链的结果不仅支持字符串输出,还能作为其他类型使用(比如数值、列表),可以重写更多魔法方法,比如__int__、__float__,或者直接在求值逻辑中返回对应类型的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:52:43