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

使用@property实现私有属性时触发AttributeError的原因排查

问题分析:Topping类的AttributeError错误原因及修复

问题代码

class Topping:
    def __init__(self, topping_type: str, weight: float):
        self.topping_type = topping_type
        self.weight = weight
        
    @property
    def topping_type(self):
        return self.__topping_type
        
    @topping_type.setter
    def topping_type(self, value):
        if self.topping_type == "":
            raise ValueError("The topping type cannot be an empty string")
        self.__topping_type = value
    
    @property
    def weight(self):
        return self.__weight
    
    @weight.setter
    def weight(self, value):
        if value <= 0:
            raise ValueError("The weight cannot be less or equal to zero")
        self.__weight = value

触发的错误

AttributeError: 'Topping' object has no attribute '_Topping__topping_type'

错误原因

  1. Setter方法中错误调用未初始化的私有属性
    在topping_type的setter方法里,你用self.topping_type == ""做判断,但self.topping_type会直接触发@property装饰的getter方法。此时__topping_type私有属性还未被赋值(还没执行到self.__topping_type = value),自然会抛出属性不存在的错误。

  2. 对Python property装饰器的理解偏差
    property是用来封装私有属性的访问接口,它不会自动将self.topping_type转为私有属性——私有属性需要你主动在setter中创建并赋值。你错误地在setter里通过getter去访问尚未初始化的私有属性,才导致了异常。

修复方案

修改setter方法,直接判断传入的value参数,而非调用getter访问未初始化的属性:

class Topping:
    def __init__(self, topping_type: str, weight: float):
        self.topping_type = topping_type
        self.weight = weight
        
    @property
    def topping_type(self):
        return self.__topping_type
        
    @topping_type.setter
    def topping_type(self, value):
        # 直接判断传入的value参数,避免调用未初始化的getter
        if value == "":
            raise ValueError("The topping type cannot be an empty string")
        self.__topping_type = value
    
    @property
    def weight(self):
        return self.__weight
    
    @weight.setter
    def weight(self, value):
        if value <= 0:
            raise ValueError("The weight cannot be less or equal to zero")
        self.__weight = value

补充说明:Python中双下划线开头的属性会被自动做名称修饰(如__topping_type转为_Topping__topping_type),目的是避免子类意外覆盖,但这个修饰过程需要你主动为属性赋值才会生效。初始化时self.topping_type = topping_type会调用setter,此时正确判断传入的value并赋值给私有属性,就能完成属性的初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:05:58