Python中的“受保护”访问 - 如何?

Posted

技术标签:

【中文标题】Python中的“受保护”访问 - 如何?【英文标题】:"Protected" access in Python - how? 【发布时间】:2013-02-09 13:20:06 【问题描述】:

我想在 Python 3.2 中设置一个具有“受保护”访问权限的类层次结构:基类的成员仅在派生类的范围内,而不是“公共”范围内。

双下划线表示成员为“私有”,单下划线表示警告,但成员仍为“公开”。指定“受保护”成员的正确语法是什么(如果有的话...)。

【问题讨论】:

不行。使用_single_underscore 约定并快乐。 【参考方案1】:

双下划线不会使 C++ 或 Java 意义上的成员成为“私有”成员 - Python 非常明确地避开了这种语言强制的访问规则。 single 下划线,按照惯例,将属性或方法标记为“实现细节”——也就是说,外部的东西仍然可以得到它,但这不是类的支持部分'接口,因此,该类可能对不变量或向后/向前兼容性做出的保证不再适用。这以不同的方式解决了与“私有”(接口和实现的分离)相同的概念问题。

双下划线调用仍然不是“私有”的名称修改 - 它只是上述内容的稍微更强的表述,其中: - 这个函数是这个类的一个实现细节,但是 - 子类可能会合理地期望有一个同名的方法,不是意味着作为原始版本的覆盖版本

这需要一点语言支持,其中__name 被修改为包含类的名称——因此它的子类版本获得不同的名称而不是覆盖。如果子类或外部代码真的想调用该方法,它仍然很有可能调用该方法 - 名称修改的目标是明确不是来防止这种情况。

但正因为如此,'protected' 在 Python 中没有多大意义 - 如果你真的有一个方法可以破坏不变量除非被子类调用 (实际上,即使您认为自己知道,您也可能不知道),Python 方式只是为了记录这一点。在您的文档字符串中添加注释以“假定仅由子类调用”,并假设客户会做正确的事情来运行 - 因为如果他们不这样做,它就会成为他们自己的问题。

【讨论】:

'双下划线不会使 C++ 或 Java 意义上的成员'私有'......' - 理解。这就是为什么在引号中说“私人”。但感谢您的复习。【参考方案2】:

Python 中的成员访问权限通过“协商”和“条约”而非强制方式起作用。

换句话说,你的班级的用户应该把他们的手放在不属于他们业务的事情上,但除了我使用_xxx 标识符之外,你不能强制执行此操作,绝对清楚他们的访问权限(通常)不是合适。

【讨论】:

所以这是不可能的。好的。但是我确实对“条约”而不是“强制”有一个问题,我已经多次表达过:访问说明符背后的想法并不是真的要阻止其他人做一些刻薄的事情。这是关于代码的清晰、结构化的组织。我希望我的语言能够帮助我做到这一点,而不是为各种疯狂的黑客行为留下空缺,这些在我经常看到的 Python 代码中都很常见。 (表明我可能不应该使用 Python...)

以上是关于Python中的“受保护”访问 - 如何?的主要内容,如果未能解决你的问题,请参考以下文章

Python - 访问类的受保护成员_

如何使伴随对象中的变量受保护

Java中的间接子类无法访问的超类中的受保护成员

为啥我不能访问子类中的受保护变量?

无法访问子类中的受保护方法[重复]

使用 Java 反射访问测试用例中的受保护方法