zoukankan      html  css  js  c++  java
  • python的伪私有属性

    伪私有属性

    类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

    “单下划线” 开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量,不能直接访问的类属性,需通过类提供的接口进行访问,不能用“from xxx import *”而导入;
    “双下划线” 开始的是私有成员,意思是只有类对象自己能访问连子类对象也不能访问到这个数据

    转载于CS实验室的大佬猫的  

    https://mp.weixin.qq.com/s?__biz=MzIzNTU1MjIxMQ==&mid=2247483658&idx=1&sn=e75ca0f76cfd3be5c94518be572c2dce&chksm=e8e42db6df93a4a047ea2539acca737d2c3a98061fd4233a1dc4f5b5d32480569615f524c9b8&mpshare=1&scene=23&srcid=0710BO36kCHKbkggf8LdxyNh#rd

     1 class Father:
     2     sex="male"
     3 
     4     def __init__(self,name,age,money=[]):
     5         self._name=name
     6         self.__age=age
     7         self.money=money
     8 
     9 class Sun(Father):
    10     def __init__(self,name,age):
    11         super(Sun,self).__init__(name,age)
    12 
    13 
    14 if __name__=="__main__":
    15     f=Father("f_name",23)
    16     s=Sun("s_name",3)
    17     print("father's default money:{}".format(f.money))
    18     f.money.append(100)
    19     print("father put 100 in money:{}".format(f.money))
    20     print("sun's default money:{}".format(s.money))
    21     s.money.append(10)
    22     print("sun put 10 in money:{}".format(s.money))
    23     print("now,father's money:{}".format(f.money))
    24 
    25     print(Father.__init__.__defaults__[0] is f.money)
    26     print(f._name is s._name)
    27     print(f._Father__age)
    28     print(s._Father__age)
    29     print(f._Father__age is s._Father__age)
    30     print(f.money is s.money)

    默认值 money=[] 在定义函数时计算(通常在加载模块时),因此默认值变成了函数对象的属性,从而修改父类的money会直接影响到子类的money

    Python 有个驻留机制,即共享字符串字面量,是一种优化措施,防止重复创建热门数字。但 CPython 不会驻留所有字符串和整数,驻留的条件是实现细节,而且没有文档说明。

    字符串驻留的范围: 0 ~ 9A ~ Z_a ~ z
    整数的驻留范围: -5 ~ 256 。
    如果字符串或整数不在上述范围,Python 就会创建一个新的对象。

    1. In [7]: a = 1

    2. In [8]: b = 1

    3. In [9]: id(a)

    4. Out[9]: 140387930888536

    5. In [10]: id(b)

    6. Out[10]: 140387930888536

    7. In [11]: c = 257

    8. In [12]: d = 257

    9. In [13]: id(c)

    10. Out[13]: 140387934343656

    11. In [14]: id(d)

    12. Out[14]: 140387934343848

  • 相关阅读:
    Mat类具体解释(二)
    Android NDK开发篇(六):Java与原生代码通信(异常处理)
    Redis源代码剖析--对象object
    NioEventLoopGroup源码分析与线程设定
    零拷贝剖析以及用户空间与内核空间切换
    Java 字符集编码
    NIO网络编程
    NIO网络访问模式实践
    Spring Boot使用Html
    内存映射文件MappedByteBuffer和Buffer的Scattering与Gathering
  • 原文地址:https://www.cnblogs.com/xiongxueqi/p/8641495.html
Copyright © 2011-2022 走看看