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之父谈Python的未来形式
Jul 01 Python
Python3实现并发检验代理池地址的方法
Sep 18 Python
Python单体模式的几种常见实现方法详解
Jul 28 Python
python 发送和接收ActiveMQ消息的实例
Jan 30 Python
python的schedule定时任务模块二次封装方法
Feb 19 Python
Python中print函数简单使用总结
Aug 05 Python
Python递归函数 二分查找算法实现解析
Aug 12 Python
基于pytorch 预训练的词向量用法详解
Jan 06 Python
解决django FileFIELD的编码问题
Mar 30 Python
Python使用多进程运行含有任意个参数的函数
May 02 Python
Python操作dict时避免出现KeyError的几种解决方法
Sep 20 Python
Pytorch 中的optimizer使用说明
Mar 03 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下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
php递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
php图形jpgraph操作实例分析
2017/02/22 PHP
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
JavaScript中Function()函数的使用教程
2015/06/04 Javascript
jquery实现超简洁的TAB选项卡效果代码
2015/08/28 Javascript
JS实现弹性菜单效果代码
2015/09/07 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
js仿淘宝和百度文库的评分功能
2016/05/15 Javascript
jQuery 插件实现随机自由弹跳气泡样式
2017/01/12 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
2017/07/27 Javascript
浅谈JsonObject中的key-value数据解析排序问题
2017/12/06 Javascript
jQuery实现的下雪动画效果示例【附源码下载】
2018/02/02 jQuery
jQuery 点击获取验证码按钮及倒计时功能
2018/09/20 jQuery
Vue中JS动画与Velocity.js的结合使用
2019/02/13 Javascript
微信小程序实现的picker多级联动功能示例
2019/05/23 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
学前端,css与javascript重难点浅析
2020/06/11 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
Python subprocess模块学习总结
2014/03/13 Python
用python读写excel的方法
2014/11/18 Python
python实现简单温度转换的方法
2015/03/13 Python
Centos Python2 升级到Python3的简单实现
2016/06/21 Python
Python实现小数转化为百分数的格式化输出方法示例
2017/09/20 Python
python编写弹球游戏的实现代码
2018/03/12 Python
python 画3维轨迹图并进行比较的实例
2019/12/06 Python
Python tkinter常用操作代码实例
2020/01/03 Python
python3用urllib抓取贴吧邮箱和QQ实例
2020/03/10 Python
基于PyInstaller各参数的含义说明
2021/03/04 Python
高中生学习生活的自我评价
2013/10/09 职场文书
国贸类专业毕业生的求职信分享
2013/12/08 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
民主评议政风行风整改方案
2014/09/17 职场文书
详解TS数字分隔符和更严格的类属性检查
2021/05/06 Javascript