Python3里的super()和__class__使用介绍


Posted in Python onApril 23, 2015

子类里访问父类的同名属性,而又不想直接引用父类的名字,因为说不定什么时候会去修改它,所以数据还是只保留一份的好。其实呢,还有更好的理由不去直接引用父类的名字,参见 Python's super() considered super! | Deep Thoughts by Raymond Hettinger。

这时候就该 super() 登场啦——

class A:

  def m(self):

    print('A')
class B(A):

  def m(self):

    print('B')

    super().m()
B().m()

当然 Python 2 里 super() 是一定要参数的,所以得这么写:
class B(A):

  def m(self):

    print('B')

    super(B, self).m()

需要提到自己的名字。这个名字也是动态查找的,在这种情况下替换第三方库中的类会出问题。

super() 很好地解决了访问父类中的方法的问题。那么,如果要访问父类的父类(准确地说,是方法解析顺序(MRO)中位于第三的类)的属性呢?

比如,B 类是继承 A 的,它重写了 A 的 m 方法。现在我们需要一个 C 类,它需要 B 类的一些方法,但是不要 B 的 m 方法,而改用 A 的。怎么间接地引用到 A 的 m 方法呢?使用self.__class__肯定是不行的,因为 C 还可能被进一步继承。

从文档中我注意到,super 的实现是通过插入一个名为 __class__ 的名字来实现的(super 会从调用栈里去查找这个 __class__ 名字)。所以,就像文档里暗示的,其实可以直接在定义方法时访问 __class__ 名字,它总是该方法被定义的类。继续我们的单字母类:

class C(B):

  def m(self):

    print('C')

    # see the difference!

    print(__class__.__mro__)

    print(self.__class__.__mro__)

    __class__.__mro__[2].m(self)
class D(C):

  def m(self):

    print('D')

    super().m()
o = D()

o.m()

会得到:
D

C

(<class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)

(<class 't.D'>, <class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)

A

不过,PyPy 并不支持这个 __class__ 名字。
Python 相关文章推荐
小小聊天室Python代码实现
Aug 17 Python
python文件特定行插入和替换实例详解
Jul 12 Python
python PyTorch参数初始化和Finetune
Feb 11 Python
Python实现爬虫抓取与读写、追加到excel文件操作示例
Jun 27 Python
Python爬虫——爬取豆瓣电影Top250代码实例
Apr 17 Python
Python解析json时提示“string indices must be integers”问题解决方法
Jul 31 Python
Python+OpenCv制作证件图片生成器的操作方法
Aug 21 Python
Python实现朴素贝叶斯的学习与分类过程解析
Aug 24 Python
Python实现名片管理系统
Feb 14 Python
Python可变对象与不可变对象原理解析
Feb 25 Python
Python unittest生成测试报告过程解析
Sep 08 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
Oct 15 Python
Python实现的飞速中文网小说下载脚本
Apr 23 #Python
Python中使用PyQt把网页转换成PDF操作代码实例
Apr 23 #Python
Python里disconnect UDP套接字的方法
Apr 23 #Python
Python实现的Google IP 可用性检测脚本
Apr 23 #Python
Python3.2中的字符串函数学习总结
Apr 23 #Python
Python与Redis的连接教程
Apr 22 #Python
Python实现的数据结构与算法之快速排序详解
Apr 22 #Python
You might like
第八节--访问方式
2006/11/16 PHP
PHP stream_context_create()作用和用法分析
2011/03/29 PHP
利用php下载xls文件(自己动手写的)
2014/04/18 PHP
PHP中使用smarty生成静态文件的例子
2014/04/24 PHP
php5.3以后的版本连接sqlserver2000的方法
2014/07/28 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
php中smarty实现多模版网站的方法
2015/06/11 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
JavaScript中的new的使用方法与注意事项
2007/05/16 Javascript
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
jQuery中对节点进行操作的相关介绍
2013/04/16 Javascript
jQuery中获取Radio元素值的方法
2013/07/02 Javascript
JavaScript模拟实现继承的方法
2015/03/30 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
BootStrap的JS插件之轮播效果案例详解
2016/05/16 Javascript
JS实现简单的天数计算器完整实例
2017/04/28 Javascript
React-Native中禁用Navigator手势返回的示例代码
2017/09/09 Javascript
Angular 中使用 FineReport不显示报表直接打印预览
2019/08/21 Javascript
TypeScript高级用法的知识点汇总
2019/12/17 Javascript
原生JS实现无缝轮播图片
2020/06/24 Javascript
详解React 元素渲染
2020/07/07 Javascript
vue 获取url里参数的两种方法小结
2020/11/12 Javascript
Python迭代用法实例教程
2014/09/08 Python
python实现用户登陆邮件通知的方法
2015/07/09 Python
django使用admin站点上传图片的实例
2019/07/28 Python
Python 为什么推荐蛇形命名法原因浅析
2020/06/18 Python
威尔逊皮革:Wilsons Leather
2018/12/07 全球购物
小学生自我评价范文
2014/01/25 职场文书
电子专业自荐信
2014/07/01 职场文书
师德师风自我剖析材料
2014/09/27 职场文书
大学学生个人总结
2015/02/15 职场文书
2015年优质护理服务工作总结
2015/04/08 职场文书
青年文明号创建口号大全
2015/12/25 职场文书
中国式结婚:司仪主持词(范文)
2019/07/25 职场文书
MySQL root密码的重置方法
2021/04/21 MySQL
VUE递归树形实现多级列表
2022/07/15 Vue.js