伪私有属性
类Example中定义的变量__X会自动变成_Example__X, 变量前有双下划线的变量被称为伪私有属性,为什么叫伪私有属性呢?因为该属性并不是私有不可改变的,在类外依旧可以通过 _类名__变量名 来调用修改该属性,那为什么需要伪私有属性的存在呢?先举例一段代码来说明
1 class C1: 2 def meth1(self): 3 self.X=88 4 def meth2(self): 5 print(self.X) 6 7 class C2: 8 def metha(self): 9 self.X=99 10 def methb(self): 11 print(self.X) 12 13 class C3(C1,C2): 14 pass 15 16 I=C3() 17 I.meth1() 18 I.metha() 19 20 I.meth2() 21 I.methb() 22 print(I.__dict__) 23 24 I._C1__X=322 #修改伪私有属性 25 print(I.__dict__) 26 27 # 99 28 # 99 29 # {‘X‘: 99} 30 # {‘X‘: 99, ‘_C1__X‘: 322}
假如类1和类2分别由程序员A和B所编写,当两个类混合在一起时,每个类的self.X得到的值取决于最后赋值的类,并不能实现本身的意义(两个程序员对自己分别编写的meth1和metha方法中X的赋值是取不同值,而并非希望类混合后X的取值相同),因而此时若两人使用的是伪私有变量就不会出现这种情况,如下:
1 class C1: 2 def meth1(self): 3 self.__X=88 4 def meth2(self): 5 print(self.__X) 6 7 class C2: 8 def metha(self): 9 self.__X=99 10 def methb(self): 11 print(self.__X) 12 13 class C3(C1,C2): 14 pass 15 16 I=C3() 17 I.meth1() 18 I.metha() 19 20 I.meth2() 21 I.methb() 22 print(I.__dict__) 23 I._C1__X=322 24 print(I.__dict__) 25 26 # 88 27 # 99 28 # {‘_C2__X‘: 99, ‘_C1__X‘: 88} 29 # {‘_C2__X‘: 99, ‘_C1__X‘: 322}
如上避免了实例中潜在的变量名冲突
进一步举例
1 class Super: 2 def method(self): 3 print(‘this is method Super‘) 4 5 class Tool: 6 def __method(self): 7 print(‘this is method Tool‘) 8 def other(self): 9 print(‘calling method __method‘) 10 self.__method() 11 12 class Sub1(Tool,Super): 13 def actions(self): 14 self.method() 15 16 class Sub2(Tool): 17 def __init__(self): 18 self.method=99 19 print(self.method) 20 21 I1=Tool() 22 I1.other() 23 print(‘************‘) 24 I2=Sub1() 25 I2.actions() 26 #对类继承树的搜索调用method的顺序本是在Tool类中搜索再在类Super中搜索 27 #但因类Tool类中method为伪私有方法并不能在Tool类外调用,因而Tool类中method方法被隐藏 28 #再到类Super中搜索,因Super类中method方法未私有化,而调用了Super类中method方法 29 print(‘-----------------‘) 30 I2.other() #继承树中搜索other方法并未被Tool类私有化,从而能通过类中other方法调用私有方法__method 31 print(‘***************‘) 32 I3=Sub2() 33 #实例化Sub2方法已不再是对父类Tool中method方法的重写,而是创建一新成员变量method 34 35 # calling method __method 36 # this is method Tool 37 # ************ 38 # this is method Super 39 # ----------------- 40 # calling method __method 41 # this is method Tool 42 # *************** 43 # 99