如何在Python中实现"保护"访问?
我想在Python 3.2中建立一个类的层次结构,使用“保护”访问权限:基类的成员只能在派生类中使用,而不是“公开”的。
在Python中,使用两个下划线会让一个成员变成“私有”,而一个下划线则表示这是个警告,但这个成员仍然是“公开”的。那么,怎么才能正确地标记一个“保护”的成员呢?
2 个回答
在Python中,双下划线并不会像C++或Java那样把一个成员变成“私有”的。Python明确不采用那种语言强制的访问规则。一个单下划线,按照惯例,表示这个属性或方法是“实现细节”——也就是说,外部仍然可以访问它,但这不是类的接口的一部分,因此,类可能对不变性或向前/向后兼容性所做的保证就不再适用了。这种方式解决了与“私有”相同的概念问题(接口和实现的分离),但方法不同。
双下划线会引发名称改名,这仍然不是“私有”的——它只是对上述内容的稍微加强的表达,具体来说: - 这个函数是这个类的实现细节,但 - 子类可能合理地期望有一个同名的方法,而这个方法并不是原始方法的重写版本。
这需要一些语言支持,__name
会被改名为包含类名的形式——这样子类版本的名称就会不同,而不是简单地覆盖原来的方法。如果子类或外部代码真的想调用这个方法,仍然是完全可能的——而名称改名的目标明确不是为了阻止这种情况。
但正因为如此,“受保护的”在Python中似乎并没有太大意义——如果你真的有一个方法可能会破坏不变性除非由子类调用(实际上,即使你认为有,可能也并不存在),Python的做法就是记录下来。在你的文档字符串中加一句“这个方法假设只会被子类调用”,然后假设使用者会做出正确的选择——因为如果他们不这样做,那就是他们自己的问题。
在Python中,成员访问的权限是通过“协商”和“协议”来实现的,而不是靠强制。
换句话说,使用你这个类的人应该不去碰那些与他们无关的东西,但你不能强制他们这样做,除了使用 _xxx
这样的命名方式,明确表示这些东西(通常)不应该被访问。