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

Python访问@property修饰的getter属性为何未抛出属性错误

问题原因解析

先看复现代码:

class A:
    def __init__(self, f, l):
        self.first = f
        self.last = l
        
    @property
    def first(self):
        return self._first
    @first.setter
    def first(self, new):
        self._first = new
        

a = A("ab", "cd")
print(a.first)

你预期会抛出AttributeError,本质是两个认知偏差:

  • 误以为类中方法的书写顺序会影响__init__运行时对类成员的访问
  • 误以为调用first的getter方法时,self._first还未初始化

实际执行逻辑如下:

  1. 类创建阶段:Python会从上到下执行完类体内的全部代码,把所有方法、类属性都绑定到类对象,类创建完成后才支持实例化操作。也就是说,哪怕你把first的property定义写在__init__后面,等你执行A("ab", "cd")调用__init__的时候,类属性first已经是同时绑定了getter、setter的完整property对象,不存在访问不到的问题。
  2. 实例初始化阶段:执行__init__里的self.first = f时,因为实例本身没有first属性,会向上查找类层面的同名成员,发现是带setter的property,赋值操作会直接被setter拦截,执行self._first = new——这一步就已经给实例绑定了_first属性,把传入的参数值"ab"存储完成,不会生成名为first的实例属性遮挡类上的property。
  3. 属性读取阶段:执行print(a.first)时,同样触发property的getter逻辑,此时self._first已经完成初始化,值为"ab",自然可以正常返回,不会抛出异常。

补充:如果删除__init__里的self.first = f赋值语句,直接访问a.first才会抛出AttributeError,因为此时实例从未通过setter创建过_first属性,getter找不到对应成员就会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:22:47