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 相关文章推荐
老生常谈进程线程协程那些事儿
Jul 24 Python
Python语言描述机器学习之Logistic回归算法
Dec 21 Python
Python Pandas找到缺失值的位置方法
Apr 12 Python
python检测空间储存剩余大小和指定文件夹内存占用的实例
Jun 11 Python
Python中fnmatch模块的使用详情
Nov 30 Python
Python构建图像分类识别器的方法
Jan 12 Python
详解python statistics模块及函数用法
Oct 27 Python
如何使用Python脚本实现文件拷贝
Nov 20 Python
对Pytorch中Tensor的各种池化操作解析
Jan 03 Python
pyspark 随机森林的实现
Apr 24 Python
解决Python 函数声明先后顺序出现的问题
Sep 02 Python
Django展示可视化图表的多种方式
Apr 08 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
php单件模式结合命令链模式使用说明
2008/09/07 PHP
php中最简单的字符串匹配算法
2014/12/16 PHP
php截取html字符串及自动补全html标签的方法
2015/01/15 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
拖动一个HTML元素
2006/12/22 Javascript
学习ExtJS(一) 之基础前提
2009/10/07 Javascript
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
关于js中alert弹出窗口文本换行问题简单详细说明
2012/12/11 Javascript
JavaScript参数个数可变的函数举例说明
2014/10/10 Javascript
node.js实现快速截图
2016/08/27 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
Bootstrap fileinput组件封装及使用详解
2017/03/10 Javascript
基于jQuery实现瀑布流页面
2017/04/11 jQuery
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
2019/08/22 Javascript
js实现转动骰子模型
2019/10/24 Javascript
Django实现的自定义访问日志模块示例
2017/06/23 Python
Python实现基于C/S架构的聊天室功能详解
2018/07/07 Python
使用Django搭建一个基金模拟交易系统教程
2019/11/18 Python
Python3 虚拟开发环境搭建过程(图文详解)
2020/01/06 Python
pycharm中leetcode插件使用图文详解
2020/12/07 Python
Python中读取文件名中的数字的实例详解
2020/12/25 Python
html5 canvas合成海报所遇问题及解决方案总结
2017/08/03 HTML / CSS
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
腾讯公司的一个sql题
2013/01/22 面试题
互联网创业计划书的书写步骤
2014/01/28 职场文书
广告学专业自荐信范文
2014/02/24 职场文书
多媒体专业自我鉴定
2014/02/28 职场文书
求职者怎样写自荐信
2014/04/13 职场文书
物流管理专业求职信
2014/05/29 职场文书
2014年社团工作总结范文
2014/11/27 职场文书
仙境之桥观后感
2015/06/16 职场文书
检讨书范文
2019/04/16 职场文书
使用pandas生成/读取csv文件的方法实例
2021/07/09 Python
JavaScript执行机制详细介绍
2021/12/06 Javascript