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

Python类开发报错:'RestaurantReview'对象无'_RestaurantReview__name'属性排查

解决Python子类访问父类私有属性的错误问题

你遇到的这个'RestaurantReview' object has no attribute '_RestaurantReview__name'错误,核心原因是Python的**名称修饰(name mangling)**机制在搞鬼,我来给你拆解清楚:

问题根源

Python中,以双下划线__开头的属性是私有属性,Python会自动把这类属性重命名为_类名__属性名的格式。比如你在Review类里定义的__name,实际会被转换成_Review__name,而不是_RestaurantReview__name。

当你在子类RestaurantReview里直接写self.__name时,Python会去寻找_RestaurantReview__name这个属性,但这个属性根本不存在——父类的私有属性是_Review__name,所以就会抛出找不到属性的错误。另外,如果你的RestaurantReview子类没有调用父类的__init__方法,那父类的私有属性甚至都没被初始化,自然也会找不到。

具体解决方案

根据你的代码,我给你两种可行的解决方式:

方案1:使用父类提供的getter方法(推荐,符合封装原则)

你的Review类已经定义了get_name()、get_date()这些getter方法,子类直接调用这些方法就能获取父类的私有属性,不需要直接访问私有变量。同时记得在子类构造函数里调用父类的__init__来初始化属性:

class Review:
    def __init__(self, nm, dt, strs):
        self.__name = nm
        self.__date = dt
        self.__stars = strs
    def set_name(self, name):
        self.__name = name
    def set_date(self, date):
        self.__date = date
    def set_stars(self,stars):
        self.__stars = stars
    def get_name(self):
        return self.__name
    def get_date(self):
        return self.__date
    def get_stars(self):
        return self.__stars  # 补充你没写完的getter

class RestaurantReview(Review):
    def __init__(self, nm, dt, strs, restaurant_name):
        # 必须调用父类构造,初始化父类的私有属性
        super().__init__(nm, dt, strs)
        self.__restaurant = restaurant_name
    
    def get_full_review(self):
        # 用父类的getter方法获取属性
        return f"{self.get_name()} reviewed {self.__restaurant} on {self.get_date()} with {self.get_stars()} stars"

方案2:将父类属性改为“受保护”的单下划线格式

如果希望子类能直接访问这些属性,可以把父类里的双下划线改成单下划线_——这是Python里约定俗成的“受保护”属性,子类可以访问,同时提醒外部代码不要直接修改:

class Review:
    def __init__(self, nm, dt, strs):
        self._name = nm  # 单下划线,受保护属性
        self._date = dt
        self._stars = strs
    # 可以保留getter/setter,也可以直接让子类访问属性
    def set_name(self, name):
        self._name = name
    def get_name(self):
        return self._name
    def set_date(self, date):
        self._date = date
    def get_date(self):
        return self._date
    def set_stars(self,stars):
        self._stars = stars
    def get_stars(self):
        return self._stars

class RestaurantReview(Review):
    def __init__(self, nm, dt, strs, restaurant_name):
        super().__init__(nm, dt, strs)
        self.__restaurant = restaurant_name
    
    def get_full_review(self):
        # 直接访问父类的受保护属性
        return f"{self._name} reviewed {self.__restaurant} on {self._date} with {self._stars} stars"

总结

  • 双下划线开头的属性是真正的私有属性,子类无法直接访问,只能通过父类提供的公共方法(比如getter/setter)操作
  • 单下划线开头的属性是受保护属性,子类可以访问,但这只是代码约定,Python不会强制限制
  • 子类必须调用父类的__init__方法,才能确保父类的属性被正确初始化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:46:59