python - Python 是否需要深入了解继承链中的所有类?

标签 python subclass private

Python 类没有公共(public)/私有(private)的概念,所以我们被告知不要触摸以下划线开头的东西,除非我们创建它。但这不需要我们直接或间接继承的所有类的完整知识吗?证人:

class Base(object):
    def __init__(self):
        super(Base, self).__init__()
        self._foo = 0

    def foo(self):
        return self._foo + 1

class Sub(Base):
    def __init__(self):
        super(Sub, self).__init__()
        self._foo = None

Sub().foo()

预计,TypeError 在评估 None + 1 时引发。所以我必须知道 _foo 存在于基类中。为了解决这个问题,可以改用 __foo,它通过修改名称来解决问题。这似乎是一个可以接受的解决方案,即使不是很优雅。但是,如果 Base 继承自一个名为 Sub 的类(在单独的包中)会怎样?现在,我的 Sub 中的 __foo 覆盖了祖 parent Sub 中的 __foo

这意味着我必须知道整个继承链,包括每个使用的所有“私有(private)”对象。 Python 是动态类型的这一事实使这变得更加困难,因为没有要搜索的声明。然而,最糟糕的部分可能是 Base 现在可能从 object 继承,但在将来的某个版本中,它会切换到从 Sub 继承>。很明显,如果我知道 Sub 是从继承而来的,我就可以重命名我的类,尽管这很烦人。但我看不到 future 。

这不是真正的私有(private)数据类型可以防止出现问题的情况吗?在 Python 中,如果某人的脚趾可能会在未来某个时刻突然出现,我如何确定我不会不小心踩到他们的脚趾?

编辑:我显然没有说清楚主要问题。我熟悉名称修饰以及单下划线和双下划线之间的区别。问题是:我如何处理我可能会与 我现在不知道其存在 的类发生冲突的事实?如果我的父类(在我没有编写的包中)碰巧开始继承与我的类同名的类,那么即使名称修改也无济于事。将此视为真正的私有(private)成员可以解决但 Python 遇到麻烦的(角落)案例,我错了吗?

编辑:根据要求,以下是一个完整示例:

文件parent.py:

class Sub(object):
    def __init__(self):
        self.__foo = 12
    def foo(self):
        return self.__foo + 1
class Base(Sub):
    pass

文件 sub.py:

import parent
class Sub(parent.Base):
    def __init__(self):
        super(Sub, self).__init__()
        self.__foo = None
Sub().foo()

调用了祖 parent 的foo,但使用了我的__foo

显然您不会自己编写这样的代码,但是 parent 可以很容易地由第三方提供,其细节可能随时更改。

最佳答案

使用private names (而不是 protected ),以双下划线开头:

class Sub(Base):
    def __init__(self):
        super(Sub, self).__init__()
        self.__foo = None
        #    ^^

不会与 Base 中的 _foo__foo 冲突。这是因为 Python 将双下划线替换为单下划线和类名;下面两行是等价的:

class Sub(Base):
    def x(self):
        self.__foo = None # .. is the same as ..
        self._Sub__foo = None

(响应编辑:)类层次结构中的两个类不仅具有相同的名称,而且它们都使用相同的属性名称,并且都使用私有(private)损坏的机会(__ ) 形式是如此之小,以至于在实践中可以安全地忽略它(到目前为止,我还没有听说过一个案例)。

但是,从理论上讲,您是正确的,因为为了正式验证程序的正确性,大多数人都知道整个继承链。幸运的是,在任何情况下,形式验证通常都需要一组固定的库。

这符合 Zen of Python 的精神, 其中包括

practicality beats purity.

关于python - Python 是否需要深入了解继承链中的所有类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11639722/

相关文章:

python - 如何将 statsmodels 测试的结果导出到 CSV?

python - Django 管理主题

java - 如何声明抽象类的所有子类都将实现 main ?

javascript - Js面向对象: private variable from a class

oop - 检查和编辑对象的私有(private)/ protected 属性

Python 将向量转换为逆频率

python - 使用 Pandas 和 NaN 滚动标准差

java - 如何子类化ConcurrentSkipListMap并设置其Comparator?

objective-c - iOS从子类调用父类方法

c++ - 我可以禁止从基类调用派生类的私有(private)成员吗?