为什么print(s._people__weight)可以而print(s._student__weight)报错

img

为什么print(s._people__weight)可以而print(s._student__weight)报错?

在Python中,以双下划线(__)开头的属性是私有属性,它们只能在类内部访问,无法在类外部直接访问。但是,您可以通过在属性名前添加一个下划线来表示这是一个受保护的属性,即可以在类外部访问,但是应该避免直接访问。

在您提供的代码中,people类的__weight属性是一个私有属性,而student类继承了people类。当您尝试访问s._people__weight时,它可以正常工作,因为Python会将以双下划线开头的属性名进行名称修饰(name mangling),即将属性名前添加类名作为前缀,以使属性变成私有的。因此,实际上您访问的是s._people__weight属性。

但是,当您尝试访问s._student__weight时,它会报错,因为它是一个不存在的属性。虽然student类继承了people类,但是student类并没有定义__weight属性,因此Python无法对其进行名称修饰,也无法找到该属性。

如果您想在student类中访问people类的私有属性__weight,可以考虑添加一个公共的方法来访问该属性,或者将__weight属性更改为受保护的属性,即将其名称修改为以单下划线开头,这样在子类中就可以直接访问该属性了。

如有帮助,请给一个采纳!

问题点:私有变量是双下划线的前缀,无法被继承和访问.
建议:将people类中的双下划线去掉就可以正常引用了.

根据GPT的回答,我进行了相关梳理,你看是否可以解除你的困惑:
根据您提供的代码,问题出在对 _student__weight 属性的访问上。在 student 类的构造函数中,您没有定义 self.__weight,而是在基类 people 的构造函数中定义的 self.__weight

由于 self.__weight 是一个私有属性,它被重命名为 _people__weight,以遵循 Python 中的名称重整规则。因此,当您尝试访问 s._people__weight 时,它能够访问到 _people__weight 私有属性并正常输出。

然而,对于 s._student__weight 的访问,由于 student 类本身没有定义 self.__weight 属性,导致无法通过该名称访问私有属性,从而抛出了 'student' object has no attribute '_student__weight' 的错误。

如果您想在 student 类中访问 self.__weight,可以通过调用基类的构造函数来设置 self.__weight,如下所示:

class student(people):
    def __init__(self,n,a,w, g):
        super().__init__(n,a,w)  # 调用基类构造函数
        self.grade = g

    def speak(self):
        print(f"{self.name} says, 'I am {self.age} years old and I am studying in grade {self.grade}'")

这样,您就可以通过 s._people__weight 访问和输出 self.__weight 了。请记住,直接通过名称访问私有属性是不推荐的做法,因为它违反了封装的原则。建议使用公共方法或属性来间接访问私有属性。