在Python中,虚函数能否是私有的?

3

我需要在Python中实现一个虚拟机制,具体实现如下:

class A() :
    def __init__(self) :
        self.level()

    def level(self) :
        print("At level A")

class B(A)
    def level(self) :
        print("At level B")

它按照预期工作:

>>>b = B()
At level B

那么我想把 level() 函数保持为私有函数,将函数名改为 __level():

class A() :
    def __init__(self) :
        self.__level()

    def __level(self) :
        print("At level A")

class B(A)
    def __level(self) :
        print("At level B")

但它没有起作用:

>>>b = B() 
At level A

当函数变为私有时,虚拟机制会神奇地丢失!有人能解释一下为什么吗?

使用单个下划线表示“私有”。两个下划线会触发名称重整。 - kindall
@kindall 但是名称混淆正是使方法变为私有的原因。 - DYZ
无论如何,名称被篡改是导致该方法未被调用的原因。 - kindall
1个回答

1
由于有一种合法的使用情况需要使用类私有成员(即避免与子类定义的名称发生名称冲突),因此有了对这种机制的有限支持,称为名称重整。请参见私有变量
class A() :
    def __init__(self) :
        self.__level()
        self._B__level()

    def __level(self) :
        print("At level A")

class B(A):
    def __level(self) :
        print("At level B")

In [228]: b=B()
At level A
At level B

由于这种混淆,__level 的 B 版本不能从 A 方法中使用(即使它们被 B 对象继承)。必须显式地使用混淆后的名称。破坏这个“虚拟”函数链接(正如您所说的)是混淆的目的,如上面的片段所述。
In [232]: b._A__level()
At level A
In [233]: b._B__level()
At level B
In [234]: b.__level()
....
AttributeError: 'B' object has no attribute '__level'

感谢@hpaulj的耐心解释和示例。这个示例引导我们了解Python的哲学。也许真正的“私有”并不存在,因为我们仍然可以通过“myclass._myclass_private”来访问“私有”。在任何涉及语言哲学的事情上,没有对错之分,只需要适应它。 - K Lamb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接