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两次?
前导双下划线名称private(意味着派生类不可用)
这不是万无一失的.它是通过修改名称来实现的. Python文档说:
形式__spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上用_classname__spam替换,其中classname是当前类名,其中前导下划线被剥离.这种修改是在不考虑标识符的句法位置的情况下完成的,因此它可以用于定义类私有实例和类变量,方法,存储在全局变量中的变量,甚至存储在实例中的变量.在其他类的实例上对此类私有.
因此__get实际上_A__get在A类中被破坏了.当B类试图引用时__get,它会被修复到_B__get不匹配的状态.
换句话说,在类Xyzzy中定义的__plugh意味着"除非你像Xyzzy一样运行,否则你不应该碰到__plugh".