结合书籍,我的理解:
前后双下划线的类中的方法:是特殊方法,用于运算符重载,可以截获运算符。
比如__init__(...)
可以截获类的实例化类名()
;
__add__
可以截获 +;
__str__
可以截获 print;
__getitem__
、__setitem__
可以截获 切片 []。
伪私有属性:私有是指不应该修改,伪私有是指可以修改。
单下划线开头的内部名称:是伪私有属性,是不应该修改的,但实际可以被修改;
class 语句内,双下划线开头但不以双下划线结尾的变量名:会自动扩张,从而包含所在类的名称。例如,C类内的__x
会自动变成_C__x
。修改后的变量名包含了所在类的名称,所以变得独特。不会和同一层次中的其他类所创建的相同变量名产生冲突。
为什么使用伪私有属性?
先来看看不使用伪私有属性,会产生什么问题。
class C1:
def meth1(self): self.x = 8
def meth2(self): print(self.x)
class C2:
def metha(self): self.x = 9
def methb(self): print(self.x)
class C(C1,C2): pass
I1 = C()
I1.meth1()
I1.metha()
I1.meth2()
print('----')
I2 = C()
I2.metha()
I2.meth1()
I2.meth2()
输出:
9
----
8
也就是说,self.x
的值取决于它最后被哪个类的哪个方法所赋值。
使用伪私有属性,解决上述问题:
class C1:
def meth1(self):
self.__x = 1
def meth2(self):
print(self.__x)
class C2:
def metha(self):
self.__x = 2
def methb(self):
print(self.__x)
class C(C1, C2):
pass
I = C()
I.meth1()
I.metha()
print(I.__dict__)
I.meth2()
I.methb()
输出:
{'_C2__x': 2, '_C1__x': 1}
1
2
参考文献:
- 《Python 学习手册(第 4 版)》- 第 26 章 - 类可以截获 Python 运算符 - P638——P641;
- 《Python 学习手册(第 4 版)》- 第 30 章 - 类的伪私有属性 - P751——P754;
- 7-python中单下划线和双下划线。