我正在try 使用名称损坏(__)来创建具有"受保护"属性的类和子类.然而,当我试图用不同的子类进一步扩展类的功能时,我得到了错误.那么,当预期父类和子类都有唯一的用例时,什么时候使用名称修改才是合适的呢?

这里有一个简单的玩具例子来说明这个问题.让我们假设Parent是一个现实主义者,所以他们看到了它的实际价值.PositiveChild的人看事情的Angular 更好,所以他们认为价值是积极的.NegativeChild的人是悲观主义者,所以他们认为这个值是负的.然而,PositiveChildNegativeChild都理解他们父母的感受,所以他们可以使用Parent‘S功能.

class Parent():
    def __init__(self, value: int) -> None: 
        self.__value = value

    def how_parent_feels(self) -> None:
        print(self.__value)

class PositiveChild(Parent):
    def __init__(self, value: int) -> None:
        super().__init__(value)
    
    def how_child_feels(self) -> None:
        print(abs(self.__value))

class NegativeChild(Parent): 
    def __init__(self, value: int) -> None:
        super().__init__(value)
    
    def how_child_feels(self) -> None:
        print(abs(self.__value) * -1)

if __name__ == "__main__":
    # This is our function. 
    val = 10

    # Here is our parent. 
    mom = Parent(val)

    # How does she feel? 
    mom.how_parent_feels()
    >>> 10

    # Here is her kids. 
    kid1 = PositiveChild(val)
    kid2 = NegativeChild(val)

    # Do they know how the mom feels? 
    kid1.how_parent_feels()
    >>> 10

    kid2.how_parent_feels()
    >>> 10

    # But how do THEY feel? 
    kid1.how_child_feels()
    >>> AttributeError: 'PositiveChild' object has no attribute '_PositiveChild__value'

    kid2.how_child_feels()
    >>> AttributeError: 'NegativeChild' object has no attribute '_NegativeChild__value'

我知道名称mangling使PositiveChildNegativeChild都具有_Parent__value属性,而这正是继承的how_parent_feels()方法所期望的,因此这种方法工作得很好.但是相应的how_child_feels()个方法需要_PositiveChild__value_NegativeChild__value个属性.那么,对于重复使用名称损坏的继承属性within subclass specific methods? Is this a misuse of "protected" python attributes and should be avoided altogether?,您有什么 Select

推荐答案

使用双下划线名称的全部要点-损坏is to prevent name collisions in subclasses.就这样.因此,这正是有意为之的行为,您已经演示的是双下划线名称损坏的规范用例!

或者说得更准确一点,就是防止accidental name collisions.关键是允许子类定义自己的self.__value变量,而不必担心父类是否使用这样的名称!它的目的是用带有访问修饰语的语言重现"私有"的这一特征,即不会出现意外的名称冲突.

不过,理解这一点非常重要,因为这些变量是可以"公开"访问的.

如果您真的想以这种方式使用双下划线名称损坏,最直接的解决方案是使用正确的变量,即_Parent__value

#in a subclass
class PositiveChild(Parent):
    def __init__(self, value: int) -> None:
        super().__init__(value)
    
    def how_child_feels(self) -> None:
        # see, all variables are always public in Python
        # this only prevents *accidental* name collisions
        # nothing is stopping you from using this variable
        print(abs(self._Parent__value))

如果要将变量标记为仅限内部使用,通常只需使用一个前导下划线.

这两种方法都同样是"私有的".PYTHON没有私有!

请注意,在带有访问修饰符的语言(如Java)中,如果您想要一个不公开但却公开给子类的变量,您将使用protected,因此有时在Python中使用该术语来引用此概念.

Python相关问答推荐

如何在Python脚本中附加一个Google tab(已经打开)

在np数组上实现无重叠的二维滑动窗口

索引到 torch 张量,沿轴具有可变长度索引

UNIQUE约束失败:customuser. username

Plotly Dash Creating Interactive Graph下拉列表

如何启动下载并在不击中磁盘的情况下呈现响应?

为什么if2/if3会提供两种不同的输出?

使用Python从rotowire中抓取MLB每日阵容

Python Pandas—时间序列—时间戳缺失时间精确在00:00

替换现有列名中的字符,而不创建新列

python sklearn ValueError:使用序列设置数组元素

干燥化与列姆化的比较

如何获得3D点的平移和旋转,给定的点已经旋转?

如何使用Azure Function将xlsb转换为xlsx?

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

如何提高Pandas DataFrame中随机列 Select 和分配的效率?

Pandas:根据相邻行之间的差异过滤数据帧

在Matplotlib中通过特定的Y值而不是 colored颜色 来改变alpha/opacity

无法从文章复制Forking 图

有可能得到事实的最后特征