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


Posted in Python onJune 27, 2019

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

class Info:
  def __init__(self):
    pass
  def calc_age(self):
    print('我是父类的方法')
class PeopleInfo(Info):
  def __init__(self):
    super().__init__()
  def calc_age(self):
    print(123456)

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

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

可以看出,父类 Info 里面的 calc_age 被子类里面的 calc_age 给“覆盖”了。

到目前为止,应该都是你已经知道的东西。那么下一个问题,请问 PeopleInfo 里面的 __init__ 会不会覆盖 Info 里面的 __init__ ?

为了确认这一点,我们来测试一下:

class Info:
  def __init__(self):
    print('我是父类的__init__')
  def calc_age(self):
    print('我是父类的方法')
class PeopleInfo(Info):
  def __init__(self):
    super().__init__()
    print('我是之类的初始化方法')
  def calc_age(self):
    print(123456)

运行效果如下图所示:

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

这里你发现父类和子类的 __init__ 都被运行了。

不过你可能会强行解释为:在子类的 __init__ 里面,有一行 super().__init__() ,这个地方可能子类还没有完全覆盖父类,所以先运行了父类的方法。等到子类的 __init__ 全部执行完成以后,才会覆盖父类。

当然,这种强行诡辩显然是错误的,但为了证明这里你看到的现象和这个 super().__init__() 没有任何关系,我们不使用 __init__ ,而是自己定义一个:

class Info:
  def __init__(self):
    pass
  def __calc_age(self):
    print('我是父类的方法')
  def run_father(self):
    self.__calc_age()
class PeopleInfo(Info):
  def __init__(self):
    super().__init__()
    pass
  def __calc_age(self):
    print(123456)
  def run_son(self):
    self.__calc_age()

运行效果如下图所示:

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

从这里可以看出,父类和子类的 __calc_age 都成功运行了。

这是因为,在Python里面,类方法或者属性如果以双下划线开头,那么他们就是类的私有方法,在被继承的时候,即使子类有相同名字的以双下划线开头的属性或者方法也不会覆盖父类。

而且这些以双下划线开头的私有方法或者属性,在类内部可以自由被其他方法调用,但是在实例对象里面是不能直接调用的,如下图所示:

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

那么Python是如何实现这一点的呢?实际上Python仅仅是改了一个名字而已。我们使用 dir 函数看看实例对象 kingname 里面有哪些内容,如下图所示:

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

大家请注意方框框住的内容,其中的 _Info__calc_age 就是父类中的 __calc_age ,而 _PeopleInfo__calc_age 就是子类中的 __calc_age 。Python仅仅是改了一个名字,在这种双下划线的私有方法或者私有属性的前面加上了 _类名 ,这样就确保了子类和父类的方法名不一致。

所以,虽然 在规范上,这种双下划线的私有方法和私有属性是不应该在外部访问的 ,但是如果你想强行访问,可以个使用这种改名以后的名字:

kingname = PeopleInfo()
kingname._PeopleInfo__calc_age() # 强行调用子类的私有方法
kingname._Info__calc_age() # 强行调用父类的私有方法

运行效果如下图所示:

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

总结

以上所述是小编给大家介绍的Python中使用双下划线防止类属性被覆盖问题,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
Python命名空间详解
Aug 18 Python
跟老齐学Python之使用Python操作数据库(1)
Nov 25 Python
Python中用于去除空格的三个函数的使用小结
Apr 07 Python
基python实现多线程网页爬虫
Sep 06 Python
python简易远程控制单线程版
Jun 20 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
Jun 18 Python
简单了解python gevent 协程使用及作用
Jul 22 Python
python opencv将表格图片按照表格框线分割和识别
Oct 30 Python
PyTorch中Tensor的数据统计示例
Feb 17 Python
keras用auc做metrics以及早停实例
Jul 02 Python
python 动态绘制爱心的示例
Sep 27 Python
python基础详解之if循环语句
Apr 24 Python
PyTorch的深度学习入门教程之构建神经网络
Jun 27 #Python
PyTorch的深度学习入门之PyTorch安装和配置
Jun 27 #Python
解决pycharm remote deployment 配置的问题
Jun 27 #Python
python turtle库画一个方格和圆实例
Jun 27 #Python
Python实现的对一个数进行因式分解操作示例
Jun 27 #Python
python pytest进阶之xunit fixture详解
Jun 27 #Python
Python批量查询关键词微信指数实例方法
Jun 27 #Python
You might like
推荐个功能齐全的发送PHP邮件类
2007/01/03 PHP
详解php的魔术方法__get()和__set()使用介绍
2012/09/19 PHP
php示例详解Constructor Prototype Pattern 原型模式
2015/10/15 PHP
PHP在线调试执行的实现方法(附demo源码)
2016/04/28 PHP
Laravel中的Auth模块详解
2017/08/17 PHP
JavaScript 学习笔记(十六) js事件
2010/02/01 Javascript
Jquery css函数用法(判断标签是否拥有某属性)
2011/05/28 Javascript
javaScript实现浮点数转十六进制字符
2013/10/29 Javascript
div模拟选择框示例代码
2013/11/03 Javascript
Jquery使用小技巧汇总
2015/12/29 Javascript
js中的DOM模拟购物车功能
2017/03/22 Javascript
javascript 缓冲运动框架的实现
2017/09/29 Javascript
在Vue项目中使用d3.js的实例代码
2018/05/01 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
浅谈Webpack4 Tree Shaking 终极优化指南
2019/11/18 Javascript
Node.JS发送http请求批量检查文件中的网页地址、服务是否有效可用
2019/11/20 Javascript
阿望教你用vue写扫雷小游戏
2020/01/20 Javascript
Python判断文件和文件夹是否存在的方法
2015/05/21 Python
在windows下快速搭建web.py开发框架方法
2016/04/22 Python
python 字典修改键(key)的几种方法
2018/08/10 Python
对python操作kafka写入json数据的简单demo分享
2018/12/27 Python
利用python在excel里面直接使用sql函数的方法
2019/02/08 Python
Python 使用多属性来进行排序
2019/09/01 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
python里的单引号和双引号的有什么作用
2020/06/17 Python
详解通过HTML5 Canvas实现图片的平移及旋转变化的方法
2016/03/22 HTML / CSS
日本索尼音乐商店:Sony Music Shop
2018/07/17 全球购物
项目专员岗位职责
2013/12/04 职场文书
银行学习十八大感想
2014/01/11 职场文书
市优秀教师事迹材料
2014/02/05 职场文书
吃空饷专项治理工作实施方案
2014/03/04 职场文书
2016年小学教师政治学习心得体会
2016/01/23 职场文书
2016年感恩父亲节活动总结
2016/04/01 职场文书
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript
Python中的 enumerate和zip详情
2022/05/30 Python