python中的双下划线

And*_*unt 9 python

class A(object):
    def __get(self):
        pass

    def _m(self):
        return self.__get()


class B(A):
    def _m(self):
        return str(self.__get())

print(A()._m())
print(B()._m())
Run Code Online (Sandbox Code Playgroud)

为什么print(A()._m())打印None,但print(B()._m())加注AttributeError: 'B' object has no attribute '_B__get'

我认为双下划线可以防止方法覆盖.

UPDATE

你写的__get是私人的.

那为什么以下工作呢?

class A(object):
    def __get(self):
        pass

    def _m(self):
        return self.__get()


class B(A):
    pass

print(A()._m())
print(B()._m())
Run Code Online (Sandbox Code Playgroud)

为什么这段代码不会引发AttributeError和打印None两次?

Dal*_*son 8

前导双下划线名称private(意味着派生类不可用)

这不是万无一失的.它是通过修改名称来实现的. Python文档说:

形式__spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上用_classname__spam替换,其中classname是当前类名,其中前导下划线被剥离.这种修改是在不考虑标识符的句法位置的情况下完成的,因此它可以用于定义类私有实例和类变量,方法,存储在全局变量中的变量,甚至存储在实例中的变量.在其他类的实例上对此类私有.

因此__get实际上_A__get在A类中被破坏了.当B类试图引用时__get,它会被修复到_B__get不匹配的状态.

换句话说,在类Xyzzy中定义的__plugh意味着"除非你像Xyzzy一样运行,否则你不应该碰到__plugh".

  • _“前导双下划线名称是`private`(意味着不可用于派生类)”_请不要这样做。Python 中有一个名为 private 的注释,这些名称是(pseudoprivate)而不是私有的。 (2认同)
  • @direprobs领先下划线的目的是隐藏除定义类之外的任何符号.在许多其他语言中,这个概念被称为"私人".因此,我使用一个单词来表达应该得到充分认可的概念.我还解释了实施细节,并提到缺乏万无一失.你还有什么建议传达这个概念? (2认同)
  • 那就是问题所在。private 这个词暗示着私有,就像在 Java 中一样,例如,不能从类外部访问该变量。您说该变量将不可用于派生类,这是绝对错误的。 (2认同)
  • 请注意,我引用的官方 python 文档将这个概念称为“类私有” (2认同)