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实现系统状态监测和故障转移实例方法
Nov 18 Python
跟老齐学Python之坑爹的字符编码
Sep 28 Python
python通过socket实现多个连接并实现ssh功能详解
Nov 08 Python
TensorFLow用Saver保存和恢复变量
Mar 10 Python
Python面向对象之类和对象实例详解
Dec 10 Python
Python OOP类中的几种函数或方法总结
Feb 22 Python
python跳出双层for循环的解决方法
Jun 24 Python
Flask配置Cors跨域的实现
Jul 12 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
Aug 12 Python
django框架ModelForm组件用法详解
Dec 11 Python
利用Python发送邮件或发带附件的邮件
Nov 12 Python
使用python求解迷宫问题的三种实现方法
Mar 17 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
mac下安装nginx和php
2013/11/04 PHP
php封装的连接Mysql类及用法分析
2015/12/10 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
javascript开发随笔二 动态加载js和文件
2011/11/25 Javascript
解决3.01版的jquery.form.js中文乱码问题的解决方法
2012/03/08 Javascript
jquery无缝向上滚动实现代码
2013/03/29 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
JQuery中操作Css样式的方法
2014/02/12 Javascript
JS删除字符串中重复字符方法
2014/03/09 Javascript
JavaScript中对象介绍
2014/12/31 Javascript
js仿搜狐视频记录片列表展示效果
2020/05/30 Javascript
原生node.js案例--前后台交互
2017/02/20 Javascript
详谈jQuery unbind 删除绑定事件 / 移除标签方法
2017/03/02 Javascript
vue.js学习之vue-cli定制脚手架详解
2017/07/02 Javascript
在Vue组件化中利用axios处理ajax请求的使用方法
2017/08/25 Javascript
Bootstrap 中data-[*] 属性的整理
2018/03/13 Javascript
GOJS+VUE实现流程图效果
2018/12/01 Javascript
vue解决花括号数据绑定不成功的问题
2019/10/30 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
[04:52]DOTA2亚洲邀请赛附加赛 TOP10精彩集锦
2015/01/29 DOTA
Python记录详细调用堆栈日志的方法
2015/05/05 Python
python实现校园网自动登录的示例讲解
2018/04/22 Python
django2.0扩展用户字段示例
2019/02/13 Python
python五子棋游戏的设计与实现
2019/06/18 Python
Django ORM 自定义 char 类型字段解析
2019/08/09 Python
学python最电脑配置有要求么
2020/07/05 Python
自学考试自我鉴定范文
2013/09/26 职场文书
目标管理责任书
2014/04/15 职场文书
《夕阳真美》教学反思
2014/04/27 职场文书
义诊活动总结
2015/02/04 职场文书
Python如何识别银行卡卡号?
2021/06/10 Python
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
2021/06/30 SQL Server