Python中使用双下划线防止类属性被覆盖问题

  

在使用Python编写面向对象的代码时,我们会常常使用“继承“这种开发方式,例如下面这一段代码:

        类信息:   def __init__(自我):   通过   def calc_age(自我):   打印(“我是父类的方法”)   类PeopleInfo(信息):   def __init__(自我):   super () . __init__ ()   def calc_age(自我):   印刷(123456)      

如果你使用PeopleInfo初始化一个对象,然后调用这个类的calc_age方法,我们来看看运行效果,如下图所示:

  

 Python中使用双下划线防止类属性被覆盖问题”>,<br/>
  </p>
  <p>可以看的出,父类信息里面的calc_age被子类里面的calc_age给“覆盖”了。</p>
  <p>到目前为止,应该都是你已经知道的东西。那么下一个问题,请问PeopleInfo里面的__init__会不会覆盖信息里面的__init__ ? </p>
  <p>为了确认这一点,我们来测试一下:</p>
  
  <pre类=   类信息:   def __init__(自我):   打印(“我是父类的__init__”)   def calc_age(自我):   打印(“我是父类的方法”)   类PeopleInfo(信息):   def __init__(自我):   super () . __init__ ()   打印(“我是之类的初始化方法”)   def calc_age(自我):   印刷(123456)      

运行效果如下图所示:

  

 Python中使用双下划线防止类属性被覆盖问题”>,</p>
  <p>这里你发现父类和子类的__init__都被运行了。</p>
  <p>不过你可能会强行解释为:在子类的__init__里面,有一行super () . __init__(),这个地方可能子类还没有完全覆盖父类,所以先运行了父类的方法。等到子类的__init__全部执行完成以后,才会覆盖父类。</p>
  <p>当然,这种强行诡辩显然是错误的,但为了证明这里你看到的现象和这个超级(). __init__()没有任何关系,我们不使用__init__,而是自己定义一个:</p>
  
  <pre类=   类信息:   def __init__(自我):   通过   def __calc_age(自我):   打印(“我是父类的方法”)   def run_father(自我):   self.__calc_age ()   类PeopleInfo(信息):   def __init__(自我):   super () . __init__ ()   通过   def __calc_age(自我):   印刷(123456)   def run_son(自我):   self.__calc_age ()      

运行效果如下图所示:

  

 Python中使用双下划线防止类属性被覆盖问题”>,<br/>
  </p>
  <p>从这里可以看的出,父类和子类的__calc_age都成功运行了。</p>
  <p>这是因为,在Python里面、类方法或者属性如果以双下划线开的头,那么他们就是类的私有方法,在被继承的时候,即使子类有相同名字的以双下划线开头的属性或者方法也不会覆盖父类。</p>
  <p>而且这些以双下划线开头的私有方法或者属性,在类内部可以自由被其他方法调用,但是在实例对象里面是不能直接调用的,如下图所示:</p>
  <p> <img src=   kingname=PeopleInfo ()   kingname._PeopleInfo__calc_age() #强行调用子类的私有方法   kingname._Info__calc_age() #强行调用父类的私有方法      

运行效果如下图所示:

  

 Python中使用双下划线防止类属性被覆盖问题”>,</p>
  <p> <h2 class=Python中使用双下划线防止类属性被覆盖问题