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

为何Python代码中__getattr__会触发__setattr__方法?

关于Python类中__setattr__两次输出的疑惑

实例化以下代码中的类D并调用d.data时,控制台输出了两次__setattr__,疑惑为何__getattr__中的return (self._attr, self._attr2)语句看似触发了对self._attr和self._attr2的赋值操作。

class D:
    def __init__(self):
        self._attr = 1
        self._attr2 = 2

    def __getattr__(self, name):
        if name == 'data':
            return (self._attr, self._attr2)

    def __setattr__(self, name, value):
        print('__setattr__')
        if name == 'data':
            self._attr, self._attr2 = value
        else:            
            super().__setattr__(name, value)

d = D()
print(d.data)  
# 输出:
# __setattr__
# __setattr__
# (1,2)

原因解析

两次__setattr__的输出并非来自调用d.data的阶段,而是来自实例化d = D()的过程:

  • 执行d = D()时,进入__init__方法,第一条语句self._attr = 1会触发自定义的__setattr__方法,打印第一次__setattr__,随后通过super().__setattr__完成_attr的赋值。
  • 紧接着执行self._attr2 = 2,同样触发__setattr__方法,打印第二次__setattr__,完成_attr2的赋值。
  • 调用d.data时,由于实例本身不存在data属性,会触发__getattr__方法,该方法只是读取已存在的self._attr和self._attr2并返回元组,整个过程没有赋值操作,不会触发__setattr__。

简单来说,你混淆了实例化阶段的赋值操作和属性访问阶段的读取操作,两次__setattr__的输出和__getattr__的return语句完全无关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:02:08