Python中私有和受保护方法的继承 [英] Inheritance of private and protected methods in Python

查看:512
本文介绍了Python中私有和受保护方法的继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,Python中没有'真正的'私有/受保护方法。这种方法并不意味着隐藏任何东西;我只是想了解Python的用途。

I know, there are no 'real' private/protected methods in Python. This approach isn't meant to hide anything; I just want to understand what Python does.

class Parent(object):
    def _protected(self):
        pass

    def __private(self):
        pass

class Child(Parent):
    def foo(self):
        self._protected()   # This works

    def bar(self):
        self.__private()    # This doesn't work, I get a AttributeError:
                            # 'Child' object has no attribute '_Child__private'

那么,这个行为是什么意思是,受保护方法将被继承,但私有根本不会被继承?

或者我错过了什么?

So, does this behaviour mean, that 'protected' methods will be inherited but 'private' won't at all?
Or did I miss anything?

推荐答案

Python没有隐私模型,没有像这样的访问修饰符在C ++,C#或Java中。没有真正的受保护或私有属性。

Python has no privacy model, there are no access modifiers like in C++, C# or Java. There are no truly 'protected' or 'private' attributes.

具有前导双下划线且没有尾随双下划线的名称​​损坏以保护他们从继承时的冲突中解脱出来。子类可以定义自己的 __ private()方法,这些方法不会干扰父类的相同名称。这些名称被视为 class private ;它们仍然可以从课外访问,但不太可能发生意外冲突。

Names with a leading double underscore and no trailing double underscore are mangled to protect them from clashes when inherited. Subclasses can define their own __private() method and these will not interfere with the same name on the parent class. Such names are considered class private; they are still accessible from outside the class but are far less likely to accidentally clash.

通过在任何此类名称前加上额外的下划线和类名来完成Mangling(无论如何如何使用名称或是否存在名称,有效地为他们提供名称空间。在 Parent 类中,任何 __ private 标识符将被替换(在编译时)名称 _Parent__private ,而在 Child 类中,标识符被 _Child__private 替换,类定义。

Mangling is done by prepending any such name with an extra underscore and the class name (regardless of how the name is used or if it exists), effectively giving them a namespace. In the Parent class, any __private identifier is replaced (at compilation time) by the name _Parent__private, while in the Child class the identifier is replaced by _Child__private, everywhere in the class definition.

以下方法有效:

class Child(Parent):
    def foo(self):
        self._protected()

    def bar(self):
        self._Parent__private()

参见 标识符的保留类


__ *

类 - 私有名称。在类定义的上下文中使用时,此类别中的名称将被重写,以使用损坏的表单来帮助避免基类和派生类的私有属性之间的名称冲突。

__*
Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between "private" attributes of base and derived classes.

和引用的文档在名称上


专用名称修改:当在类定义中以文本形式出现的标识符时以两个或多个下划线字符开头,并且不以两个或多个下划线结尾,它被视为该类的私有名称。在为它们生成代码之前,将私有名称转换为更长的形式。转换将在名称前插入类名,删除前导下划线并插入单个下划线。例如,名为Ham的类中出现的标识符 __ spam 将转换为 _Ham__spam 。此转换独立于使用标识符的语法上下文。

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam. This transformation is independent of the syntactical context in which the identifier is used.

除非,否则不要使用类 - 私有名称>具体而言希望避免告诉开发人员想要将您的类子类化为不能使用某些名称或冒险破坏您的类。除了已发布的框架和库之外,此功能几乎没用。

Don't use class-private names unless you specifically want to avoid having to tell developers that want to subclass your class that they can't use certain names or risk breaking your class. Outside of published frameworks and libraries, there is little use for this feature.

PEP 8 Python样式指南有关于私人名称修改的说法:

The PEP 8 Python Style Guide has this to say about private name mangling:


如果您的类要进行子类化,并且您有不希望子类使用的属性
,请考虑使用
双引导下划线和没有尾随下划线来命名它们。这将调用
Python的名称修改算法,其中类的名称是
,被绑定到属性名称中。这有助于避免属性名称
冲突如果子类无意中包含具有
同名的属性。

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

注意1:请注意,只有简单的类名是在损坏的
名称中使用,因此如果子类选择相同的类名和属性
name,您仍然可以获得名称冲突。

Note 1: Note that only the simple class name is used in the mangled name, so if a subclass chooses both the same class name and attribute name, you can still get name collisions.

注意2:名称修改可以进行某些用途,例如调试和
__ getattr __(),不太方便。然而,名称修改算法
已有详细记录并且易于手动执行。

Note 2: Name mangling can make certain uses, such as debugging and __getattr__(), less convenient. However the name mangling algorithm is well documented and easy to perform manually.

注3:并非所有人都喜欢名称修改。尝试平衡需要
避免意外姓名冲突与高级来电者可能使用。

Note 3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers.

这篇关于Python中私有和受保护方法的继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆