python 为什么示例变量的前缀对于父类和子类都保持相同?

3z6pesqy  于 2023-05-27  发布在  Python
关注(0)|答案(2)|浏览(110)

我有两门课,矩形课和正方形课。Square是Rectangle的子类。我的问题是,当我为任何一个类放入一个self.dict语句来检查它们的示例的值时,它们的关键字中都有前缀**_Rectangle**。例如,矩形示例和正方形示例的宽度都将具有关键字**_Rectangle__width**。我得到前缀是因为我把所有属性初始化为私有属性,但是为什么当它是一个正方形示例时前缀没有改变呢?我假设对于一个square示例,width关键字应该是**_Square__width**。这是因为我正在使用super()函数初始化square类的值吗?这是我的代码。

class Rectangle(Base):
    def __init__(self, width, height, x=0, y=0, id=None):
        super().__init__(id)
        self.__width = width
        self.__height = height
        self.__x = x
        self.__y = y

    def to_dictionary(self):
        return self.__dict__

class Square(Rectangle):
    def __init__(self, size, x=0, y=0, id=None):
        super().__init__(size, size, x, y, id)

    def to_dictionary(self):
        return self.__dict__

我使用下面的代码测试了main中的函数。

r2 = Rectangle(5, 5, 5, 5)
rectangle_dict = r2.to_dictionary()
print(rectangle_dict)

s2 = Square(4, 4, 4)
square_dict = s2.to_dictionary()
print(square_dict)

结果是

{'id': 1, '_Rectangle__width': 5, '_Rectangle__height': 5, '_Rectangle__x': 5, '_Rectangle__y': 5}
{'id': 2, '_Rectangle__width': 4, '_Rectangle__height': 4, '_Rectangle__x': 4, '_Rectangle__y': 4}

所有的关键字前缀都是相同的。为什么会这样?我知道Square类中的to_dictionary方法是不必要的,因为它可以很容易地从Rectangle类继承相同的方法,但结果与上面相同。

snvhrwxg

snvhrwxg1#

Square.__init__调用super()super()调用Rectangle.__init__,这就是分配私有变量的地方。私有变量只能由定义它们的类使用。继承人没有权利摆弄它们。这就是他们存在的真正原因。如果你想让像Square这样的继承者看到这些变量,你不应该把它们设为类的私有变量。

q0qdq0h2

q0qdq0h22#

这就是“私有”属性(以双下划线开头的属性)在python中的工作方式。从文档
任何形式为__spam的标识符(至少两个前导下划线,最多一个尾随下划线)都被文本替换为_classname__spam,其中classname是去掉前导下划线的当前类名。(...)
名称修改的目的是给予类一种简单的方法来定义“私有”示例变量和方法,而不必担心派生类定义的示例变量,或者通过类外的代码来破坏示例变量。请注意,mangling规则主要是为了避免事故而设计的;确定的灵魂仍然可以访问或修改被认为是私有的变量。
因此,您“不能”覆盖这样的变量,在Square中定义__width将创建两个字段Rectangle__widthSquare__width

相关问题