zzyzz
 1 Private Variable and Private Method
2    Python 不象 Java 那样, 通过 private 关键字创建私有属性, python 通过更简洁的实现了\'私有属性\', 从而避免了子类意外覆盖私有属性. 3 举个例子来说, 现在编写一下儿名字叫 Robot 的类,并实现了一个名字为 fighting 的属性。 4 接着又人编写了一个叫 Camaro 的类, 并继承了 Robot 类, 并在其中构造了 fighting 的属性, 这个时候 Robot 的 fighting 属性被覆盖了. 5 而恰巧 Robot 类的编写者的意图是 - 不允许所有 Robot 的子类访问 fighting(可能为了世界和平), 显然 Camaro 这个子类破坏了这一点. 6 7 为了避免这种情况, Robot 类的编写者可以以 __fighting (或者 __fighting_) 来命名要私自属性(声明成成私有属性). 8 这时 Python 的解释器会该属性 \'修饰\' 后再添加到 __dict__ 属性中, 该例中会变成 _Robot__fighting, 而不是 __fighting (原形式) 9 Python 的这种特性被称为 name mangling. 10 注, 名称改写(name mangling),Python 解释器在运行时自动把私有属性 __x (或 __x_)重命名为 _MyClass__X (或 _MyClass__X_) 11 12 以上文字所对应的例子, 13 class Robot(object): 14 __RB = 3 15 __RB_ = 5 16 def __fighting(self): 17 print(\'This is \\'_MyClass__X\\' format\') 18 19 def __fighting_(self): 20 print(\'This is \\'_MyClass__X_\\' format\') 21 22 def func(self): 23 print(\'Called via - A\') 24 25 class Camaro(Robot): 26 def func(self): 27 print(\'Called via - B\') 28 29 if __name__ == "__main__": 30 print(Robot.__dict__) #1 31 a = Camaro() 32 a.func() #2 33 print(Camaro.__mro__) #3 34 super(Camaro,a).func() #3 35 a._Robot__fighting() #4 36 a._Robot__fighting_() #4 37 a.__fighting #5 38 39 Output, 40 {\'__module__\': \'__main__\', \'_Robot__RB\': 3, \'_Robot__RB_\': 5,\'_Robot__fighting\': <function Robot.__fighting at 0x039C6300>, 41 \'_Robot__fighting_\': <function Robot.__fighting_ at 0x039C62B8>, 42 \'func\': <function Robot.func at 0x039C6270>, ...} 43 #1 |^ 添加到 __dict__ 中的是 \'_MyClass__X\' 或者 \'_MyClass__X_\' - name mangling 44 Called via - B #2 子类的中方法覆盖了父类中的\'同名\'方法 45 (<class \'__main__.Camaro\'>, <class \'__main__.Robot\'>, <class \'object\'>) #3 MRO __mro__ 46 Called via - A #3 super 指的并不一定是\'父类\', 而是 MRO 中的\'下一个\' ****** 47 This is \'_MyClass__X\' format #4 name mangling ; 知道 name mangling 规则后 可以 hack 私有属性 48 This is \'_MyClass__X_\' format #4 name mangling ; 知道 name mangling 规则后 可以 hack 私有属性 49 a.__fighting 50 AttributeError: \'Camaro\' object has no attribute \'__fighting\' #5 常规方法调用属性报错(AttributeError), 因为 __dict__ 没有相应属性

 

分类:

技术点:

相关文章: