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

class Info:def __init__(self):passdef calc_age(self):print('我是父类的方法')
class PeopleInfo(Info):def __init__(self):super().__init__()def calc_age(self):print(123456)
复制代码

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

Python学习交流群:1004391443

可以看出,父类 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)
复制代码

运行效果如下图所示:

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

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

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

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

运行效果如下图所示:

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

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

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

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

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

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

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

运行效果如下图所示:

双继承_在Python中使用双下划线防止类属性被覆盖!相关推荐

  1. python类的属性前加上双下划线_在Python中使用双下划线防止类属性被覆盖

    在使用Python编写面向对象的代码时,咱们会经常使用"继承"这种开发方式.例以下面这一段代码:python class Info: def __init__(self): pas ...

  2. python中五种下划线 _

    python中五种下划线 "_" 单前导下划线:_var 单末尾下划线:var_ 双前导下划线:__var 双前导和末尾下划线:var 单下划线:_ 在文章结尾处,你可以找到一个简 ...

  3. Python 中5种下划线的含义都是什么?

    今天给大家科普一波,单下划线和双下划线在Python变量和方法名称的含义.有一些含义仅仅是依照约定,被视作提示,而有一些含义是由Python解释器严格执行的.在Python变量和方法名称中各种单下划线 ...

  4. python中的单下划线和双下划线_python 里面的单下划线与双下划线的区别(私有和保护)...

    Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划 ...

  5. python中的单下划线和双下划线_python中的单下划线和双下划线

    1. _ 的含义在python的类中,没有真正的私有化,不管是方法还是属性,为了编程的需要,约定加了下划线 _ 的属性和方法不属于API,不应该在类的外面访问,也不会被from M import * ...

  6. python中的符号下划线_详解Python中下划线的使用方法

    编程派微信号:codingpy 这篇文章讨论Python中下划线_的使用.跟Python中很多用法类似,下划线 _ 的不同用法绝大部分(不全是)都是一种惯例约定. 单个下划线(_) 主要有三种情况: ...

  7. Python中5种下划线的含义

     1.变量名前只有一个下划线(_X):按照约定俗成的规定,当你看到这样的变量时,意思就是,"虽然我可以被访问,但是,请把我视为私有变量,不要随意访问". 2.变量名前有两个下划线( ...

  8. python写入csv文件时携带双引号_在Python中解析csv时由于双引号导致的问题.

    我有以下格式的csv文件, "1";"A";"A:"61 B & BA";"C" 以下是我读取csv文 ...

  9. python子类定制_在Python中实现可定制的Lexer类

    我想实现一个可定制和可扩展的lexer类.在 我的想法 2种不同类型的处理程序:字符集处理程序 函数处理程序 当一个字符被读取时,它被推送到所有注册到lexer的处理程序中.一旦处理程序匹配并返回一个 ...

最新文章

  1. Django源码分析7:migrate命令的浅析
  2. jstatd - Virtual Machine jstat Daemon
  3. sed 命令自己总结
  4. 【上】安全HTTPS-全面详解对称加密,非对称加密,数字签名,数字证书和HTTPS
  5. java怎么输出集合_Java 输出集合中的元素
  6. HuaWeiCloud_model_arts
  7. Selenium Xpath元素无法定位 NoSuchElementException: Message: no such element: Unable to locate element
  8. 详细解析WSAEventSelect模型
  9. android html图片点击事件,Android TextView加载HTMl图文之添加点击事件和查看图片
  10. Java方法中的参数太多,第7部分:可变状态
  11. WPF学习(3) – WPF控件
  12. php冒泡排序的用途,浅谈php冒泡排序
  13. springboot maven打包pom配置
  14. Android蓝牙操作笔记
  15. opencv之绘制带箭头的线段---arrowedLine
  16. linux文件夹权限_五分钟搞定 Linux 文档全部知识,就看这篇文章
  17. Eclipse SVN插件版本
  18. 软件测试术语中英文对照
  19. mysql增删改查语法
  20. everedit 保存机器学习路径注意事项

热门文章

  1. css3动画过渡按钮
  2. Redis数据类型--散列类型
  3. C++多重继承师生类复盘
  4. 带有下标的赋值维度不匹配_不稳定的期权时间价值
  5. android ui怎么用ps切图,怎样用ps对设计稿进行一键切图?
  6. C++中关于隐藏的理解
  7. IOS – OpenGL ES 调节图像色度 GPUImageHueFilter
  8. 变量命名 – 匈利亚命名法则 - C语言零基础入门教程
  9. Python 字典推导式 - Python零基础入门教程
  10. BugkuCTF-MISC题telnet