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

Python中__str__实现为何可使用self._diameter却不能用self._area?

Python @property装饰器中self._area访问报错的原因解析

我在学习Python的@property装饰器时遇到一个问题:创建了一个Circle类,在__str__方法里用self.area能正常运行,但换成self._area就抛出AttributeError: Circle object has no attribute _area错误,同时self._diameter却能正常访问,这是为什么?

附带的代码如下:

class Circle(object):
    def __init__(self, radius): 
        self._radius=radius
    
    @property
    def radius(self):
        return self._radius
        
    @radius.setter
    def radius(self, radius):
        self._radius=radius
    
    @property 
    def diameter(self):
        return self._diameter
    
    @diameter.setter
    def diameter(self, diameter):
        self._diameter=diameter
    
    @diameter.deleter
    def diameter(self):
        del self._diameter
    
    @property
    def area(self):
        self._area = self._radius**2*3.14
        return self._area

        
    def __str__(self):
        return f'Circle has radius of {self._radius}, diameter of {self._diameter}, and area of {self.area}'    
        
c = Circle(4)
c.diameter=3
print(str(c))

核心原因分析

  1. self._diameter能访问的原因
    代码里执行了c.diameter=3,这触发了diameter属性的setter方法,该方法明确给self._diameter赋了值。所以当__str__里访问self._diameter时,这个属性已经存在于实例对象中,能正常读取。

  2. self._area访问报错的原因
    area是只读的property(没有对应的setter方法),它的getter方法里虽然写了self._area = ...,但这个赋值操作只有在调用self.area的时候才会执行。如果直接访问self._area却从未调用过self.area,实例里根本不存在_area这个属性,就会抛出属性不存在的错误。

    另外,当前area的实现存在冗余:每次调用self.area都会重新计算并覆盖self._area,完全没必要存储这个值,直接返回计算结果更合理。

修正建议

把area的property改成直接返回实时计算结果,不需要依赖_area实例属性:

@property
def area(self):
    return self._radius ** 2 * 3.14

这样不管什么时候调用self.area,都会基于当前的_radius计算结果,既避免了冗余存储,也彻底消除了直接访问_area可能带来的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:15:37