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 相关文章推荐
python3.0 字典key排序
Dec 24 Python
python二叉树的实现实例
Nov 21 Python
用python + openpyxl处理excel2007文档思路以及心得
Jul 14 Python
使用Python的Twisted框架编写简单的网络客户端
Apr 16 Python
python实现同时给多个变量赋值的方法
Apr 30 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
Nov 29 Python
python爬虫获取多页天涯帖子
Feb 23 Python
python socket网络编程之粘包问题详解
Apr 28 Python
详解Django中间件的5种自定义方法
Jul 26 Python
python查看文件大小和文件夹内容的方法
Jul 08 Python
Python爬虫 urllib2的使用方法详解
Sep 23 Python
python如何查看安装了的模块
Jun 23 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 ajax异步读取rss文档数据
2016/03/29 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
2017/05/02 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
Jquery跨域获得Json时invalid label错误的解决办法
2011/01/11 Javascript
修改file按钮的默认样式实现代码
2013/04/23 Javascript
使用js判断控件是否获得焦点
2014/01/03 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
逻辑表达式中与或非的用法详解
2016/06/06 Javascript
javascript中的try catch异常捕获机制用法分析
2016/12/14 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
微信小程序之电影影评小程序制作代码
2017/08/03 Javascript
微信小程序录音与播放录音功能
2017/12/25 Javascript
详解easyui 切换主题皮肤
2019/04/04 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
AJAX XMLHttpRequest对象创建使用详解
2020/08/20 Javascript
vue3+typescript实现图片懒加载插件
2020/10/26 Javascript
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Pandas探索之高性能函数eval和query解析
2017/10/28 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
Python求出0~100以内的所有素数
2018/01/23 Python
Python处理中文标点符号大集合
2018/05/14 Python
python+tifffile之tiff文件读写方式
2020/01/13 Python
Python Django中的STATIC_URL 设置和使用方式
2020/03/27 Python
Python3.9新特性详解
2020/10/10 Python
Under Armour西班牙官网:美国知名的高端功能性运动品牌
2018/12/12 全球购物
德国便宜的宠物店:Brekz.de
2020/10/23 全球购物
.net软件工程师面试题
2015/03/31 面试题
爽歪歪广告词
2014/03/20 职场文书
小学生综合素质评语
2014/04/23 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
开票证明
2015/06/23 职场文书
如何把新闻人物写得立体、鲜活?
2019/08/14 职场文书
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技