简体   繁体   English

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

[英]“Protected” access in Python - how?

I would like to set up a class hierarchy in Python 3.2 with 'protected' access: Members of the base class would be in scope only for derived classes, but not 'public'. 我想在Python 3.2中使用'protected'访问来设置一个类层次结构:基类的成员只在派生类的范围内,而不是'public'。

A double underscore makes a member 'private', a single underscore indicates a warning but the member remains 'public'. 双下划线使成员“私有”,单个下划线表示警告但成员仍为“公共”。 What (if any...) is the correct syntax for designating a 'protected' member. 什么(如果有的话)是指定“受保护”成员的正确语法。

Member access allowance in Python works by "negotiation" and "treaties", not by force. Python中的成员访问权限通过“协商”和“条约”来实现,而不是通过武力。

In other words, the user of your class is supposed to leave their hands off things which are not their business, but you cannot enforce that other than my using _xxx identifiers making absolutely clear that their access is (normally) not suitable. 换句话说,你的班级的用户应该把他们的手放在不属于他们业务的东西上,但你不能强制执行除了我使用_xxx标识符之外的其他标识,使得他们的访问权限(通常)不合适。

Double underscores don't make a member 'private' in the C++ or Java sense - Python quite explicitly eschews that kind of language-enforced access rules. 双下划线不会使成员在C ++或Java意义上成为“私有” - Python非常明确地避开了那种语言强制的访问规则。 A single underscore, by convention, marks an attribute or a method as an "implementation detail" - that is, things outside can still get to it, but this isn't a supported part of the class' interface and, therefore, the guarantees that the class might make about invariants or back/forwards compatibility no longer apply. 按照惯例, 单个下划线将属性或方法标记为“实现细节” - 也就是说,外部的东西仍然可以到达它,但这不是类接口的受支持部分,因此,保证该类可能使不变量或后向/向前兼容性不再适用。 This solves the same conceptual problem as 'private' (separation of interface and implementation) in a different way. 这以不同的方式解决了与“私有”(接口和实现的分离)相同的概念问题。

Double underscores invoke name mangling which still isn't 'private' - it is just a slightly stronger formulation of the above, whereby: - This function is an implementation detail of this class, but - Subclasses might reasonably expect to have a method of the same name that isn't meant as an overridden version of the original 双下划线调用仍然不是'私有'的名称修改 - 它只是上面稍微强一些的表达式,其中: - 这个函数是这个类的实现细节, 但是 - 子类可能合理地期望有一个方法相同的名称, 不是原始的重写版本

This takes a little bit of language support, whereby the __name is mangled to include the name of the class - so that subclass versions of it get different names instead of overriding. 这需要一些语言支持,其中__name被修改为包含类的名称 - 因此它的子类版本获得不同的名称而不是覆盖。 It is still quite possible for a subclass or outside code to call that method if it really wants to - and the goal of name mangling is explicitly not to prevent that. 如果子类或外部代码确实需要调用该方法,那么它仍然很有可能 - 并且名称修改的目标明确不是为了防止这种情况。

But because of all this, 'protected' turns out not to make much sense in Python - if you really have a method that could break invariants unless called by a subclass (and, realistically, you probably don't even if you think you do), the Python Way is just to document that. 但是由于所有这些,'protected'在Python中没有多大意义 - 如果你真的有一个方法可以打破不变量, 除非被一个子类调用 (并且,实际上,即使你认为你做了,你可能也不会),Python方法就是记录它。 Put a note in your docstring to the effect of "This is assumed to only be called by subclasses", and run with the assumption that clients will do the right thing - because if they don't, it becomes their own problem. 在你的docstring中注意“这假定只能由子类调用”的效果,并假设客户端会做正确的事情 - 因为如果它们不这样做,它就成了他们自己的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM