You need to enable JavaScript to run this app. Python 3.x环境下如何实现点运算符与__getattribute__的一致重载?
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.x环境下如何实现点运算符与__getattribute__的一致重载?

Python 3.x 点运算符重载的一致性实现需求

基础前提

  • 本次讨论仅基于Python 3.x及以上版本,不涉及Python 2.x的兼容场景
  • 和多数编程语言规则一致,Python的点运算符用于实例的属性访问,例如对Rectangle实例的属性取值操作:
# 创建Rectangle类的新实例
robby = Rectangle(3, 10)

# 调用点运算符       
x = robby.length 
  • 常规认知中,上述属性取值逻辑等价于x = Rectangle.__getattribute__(robby, "length"),即点运算符的行为通常被认为由__getattribute__方法完全接管,但实际运行逻辑并非完全符合该认知。

魔法方法的特殊调用规则

Python中存在一类名称前后均以双下划线包裹的特殊方法,即魔法方法,典型示例为__len__()。
执行如下代码即可获取内置int类型支持的绝大多数魔法方法列表:

print("\n".join(filter(lambda s: s.startswith("__"), dir(int))))

输出的方法列表节选如下:

__abs__
__add__
__and__
__bool__
__ceil__
__class__
__delattr__
__dir__
__divmod__
__doc__
__eq__
__float__
[... 内容截断 ...]
__rtruediv__
__rxor__
__setattr__
__sizeof__
__str__
__sub__
__subclasshook__
__truediv__
__trunc__
__xor__

重写__getattribute__的失效场景

实际开发中,自定义继承自object的类并重写object.__getattribute__时,自定义逻辑往往无法达到预期:Python会在部分场景下直接忽略重写后的点运算符逻辑,例如下述Klass类的实现:

class Klass:
    def __getattribute__(self, attr_name):
        return print

obj = Klass()

obj.append()  # 可正常运行,obj.append == print
obj.delete()  # 可正常运行,obj.delete == print
obj.length    # 可正常运行
obj.x         # 可正常运行

# 下述涉及魔法方法调用的逻辑均无法触发自定义的__getattribute__

# 下述代码等价于 x = Klass.__len__(obj)
len(obj)

# 等价于 x = Klass.__add__(obj, 5)
x = obj + 5

# 等价于 x = Klass.__radd__(obj, 2)
x = 2 + obj

核心实现目标

目前已知Python存在多种可重载点运算符的实现方案,我们需要筛选出可读性强、逻辑简洁、行为一致的实现方案:

  • 行为一致的定义为:只要源码中使用点运算符获取属性,无论对应属性是普通方法还是魔法方法,都能触发自定义的点运算符逻辑
  • 避免手动逐一为所有已知魔法方法编写实现,防止产生大量如下的样板冗余代码:
def __len__(*args, **kwargs):
    return getattr(args[0], "__len__")(*args, **kwargs)

说明:我们已经清楚__getattr__与__getattribute__的设计区别,核心待解决的问题并非选择重写哪一个方法的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.10 14:45:03