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实现基本进制转换的方法
Jul 11 Python
python3 shelve模块的详解
Jul 08 Python
基于Django的ModelForm组件(详解)
Dec 07 Python
Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例
Mar 15 Python
对Python3.x版本print函数左右对齐详解
Dec 22 Python
Python中最大递归深度值的探讨
Mar 05 Python
python利用re,bs4,requests模块获取股票数据
Jul 29 Python
python GUI库图形界面开发之PyQt5美化窗体与控件(异形窗体)实例
Feb 25 Python
jupyter lab文件导出/下载方式
Apr 22 Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
Jun 04 Python
python中rc1什么意思
Jun 19 Python
Python文件的操作示例的详细讲解
Apr 08 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
在apache下限制每个虚拟主机的并发数!!!!
2006/10/09 PHP
浅析PHP中Collection 类的设计
2013/06/21 PHP
PHP实现获取域名的方法小结
2014/11/05 PHP
CodeIgniter针对lighttpd服务器URL重写的方法
2015/06/10 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
Javascript 不能释放内存.
2006/09/07 Javascript
jQuery中attr()和prop()在修改checked属性时的区别
2014/07/18 Javascript
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
2015/08/21 NodeJs
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
2016/06/16 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
有关JS中的0,null,undefined,[],{},'''''''',false之间的关系
2017/02/14 Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
2018/01/02 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
vue全局自定义指令-元素拖拽的实现代码
2019/04/14 Javascript
koa router 多文件引入的方法示例
2019/05/22 Javascript
vue实现路由监听和参数监听
2019/10/29 Javascript
原生js+css调节音量滑块
2020/01/15 Javascript
python使用wxPython打开并播放wav文件的方法
2015/04/24 Python
Python中使用asyncio 封装文件读写
2016/09/11 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
Python通过调用有道翻译api实现翻译功能示例
2018/07/19 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
使用Python-OpenCV向图片添加噪声的实现(高斯噪声、椒盐噪声)
2019/05/28 Python
python 一个figure上显示多个图像的实例
2019/07/08 Python
python函数的作用域及关键字详解
2019/08/20 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
python如何停止递归
2020/09/09 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
2020/12/16 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
Diamondback自行车:拥有你的冒险
2019/04/22 全球购物
阿里巴巴美国:Alibaba美国
2019/11/24 全球购物
应征英语教师求职信
2013/11/27 职场文书
简历的自荐信
2013/12/19 职场文书
服务口号大全
2014/06/11 职场文书
企业领导班子四风对照检查材料
2014/09/27 职场文书