Python的私有属性和“受保护的”属性

摘自《流畅的Python》

Python 不能像Java 那样使用private 修饰符创建私有属性,但是Python 有个简单的机制,能避免子类意外覆盖“私有”属性。

举个例子。有一个Dog 类,这个类的内部用到了mood 实例属性,但是没有将其开放。现在,你创建了Dog 类的子类:Beagle。如果你在毫不知情的情况下又创建了名为mood 的实例属性,那么在继承的方法中就会把Dog 类的mood 属性覆盖掉。

为了避免这种情况,如果以__mood 的形式(两个前导下划线,尾部没有或最多有一个下划线)命名实例属性,Python 会把属性名存入实例的__dict__ 属性中,而且会在前面加上一个下划线和类名。因此,对Dog 类来说,__mood 会变成_Dog__mood;对Beagle 类来说,会变成_Beagle__mood。这个语言特性叫名称改写(name mangling)。

>>> v1 = Vector2d(3, 4)
>>> v1.__dict__
{'_Vector2d__y': 4.0, '_Vector2d__x': 3.0}
>>> v1._Vector2d__x
3.0

名称改写是一种安全措施,不能保证万无一失:它的目的是避免意外访问。只要知道改写私有属性名的机制,任何人都能直接读取私有属性——这对调试和序列化倒是有用。此外,只要编写v1._Vector__x = 7 这样的代码,就能轻松地为Vector2d 实例的私有分量直接赋值。

Python 文档的某些角落把使用一个下划线前缀标记的属性称为“受保护的”属性。使用self._x 这种形式保护属性的做法很常见。Python 解释器不会对使用单个下划线的属性名做特殊处理,不过这是很多Python 程序员严格遵守的约定,他们不会在类外部访问这种属性。

发布了0 篇原创文章 · 获赞 0 · 访问量 148

猜你喜欢

转载自blog.csdn.net/Airfrozen/article/details/104354596