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

Python中@property相关疑问:getter触发与递归原因解析

Python属性访问与递归问题解析

原始代码

class Person():

    def __init__(self,name:str,height :float) -> None:
        #initialize
        self.__name=name
        self.height=height
    
    @property
    def name(self) -> str:
        print("Inside Getter")
        return self.__name
    
    @name.setter
    def name(self, value):
        print("New name being set")
        self.name = value

    def __repr__(self) -> str:
        return f"({self.__class__.__name__}:{self.name},{self.height})"

p=Person("Sam",180.00)
print(p)

问题1:self.name为何触发getter方法?

在上述代码中,当在__repr__方法中以self.name访问属性时,会先调用name的getter方法,再执行__repr__;但用self.__name访问则仅执行__repr__。这是为什么?

代码运行输出

Inside Getter
(Person:Sam,180.0)

解答

这是@property装饰器的特性导致的:

  • 给name方法加上@property后,Python会把这个方法包装成属性的getter访问器。此时通过self.name访问时,Python不会直接查找实例的name属性,而是自动调用你定义的def name(self)方法。
  • self.__name是Python的**名称改写(name mangling)**机制:双下划线开头的属性会被Python自动重命名为_类名__属性名(这里就是_Person__name),它是实例直接存储的属性,和@property定义的name访问器没有关联,所以访问它不会触发getter。

问题2:修改后为何出现递归错误?

把getter方法改为如下形式(移除双下划线):

def name(self) -> str:
    print("Inside Getter")
    return self.name

此时运行会抛出递归错误,请问递归是如何产生的?

报错信息

in name
print("Inside Getter")
RecursionError: maximum recursion depth exceeded while calling a Python object

解答

递归的循环逻辑非常直接:

  1. 当通过self.name访问时,因为name被@property修饰,Python会调用这个getter方法。
  2. 但在getter方法内部,你写了return self.name,这会再次触发name的getter方法调用。
  3. 这个调用循环会无限重复,直到达到Python预设的最大递归深度,最终抛出RecursionError。

简单来说就是:getter方法内部又调用了自身的属性访问,导致无限递归调用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:35:28