我有两门课,矩形课和正方形课。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类继承相同的方法,但结果与上面相同。
2条答案
按热度按时间snvhrwxg1#
Square.__init__
调用super()
,super()
调用Rectangle.__init__
,这就是分配私有变量的地方。私有变量只能由定义它们的类使用。继承人没有权利摆弄它们。这就是他们存在的真正原因。如果你想让像Square
这样的继承者看到这些变量,你不应该把它们设为类的私有变量。q0qdq0h22#
这就是“私有”属性(以双下划线开头的属性)在python中的工作方式。从文档
任何形式为__spam的标识符(至少两个前导下划线,最多一个尾随下划线)都被文本替换为_classname__spam,其中classname是去掉前导下划线的当前类名。(...)
名称修改的目的是给予类一种简单的方法来定义“私有”示例变量和方法,而不必担心派生类定义的示例变量,或者通过类外的代码来破坏示例变量。请注意,mangling规则主要是为了避免事故而设计的;确定的灵魂仍然可以访问或修改被认为是私有的变量。
因此,您“不能”覆盖这样的变量,在
Square
中定义__width
将创建两个字段Rectangle__width
和Square__width