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通过PIL获取图片主要颜色并和颜色库进行对比的方法
Mar 19 Python
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
Python中多线程的创建及基本调用方法
Jul 08 Python
Python实现定时精度可调节的定时器
Apr 15 Python
python得到windows自启动列表的方法
Oct 14 Python
python3人脸识别的两种方法
Apr 25 Python
如何通过Python实现标签云算法
Jul 02 Python
Python虚拟环境的原理及使用详解
Jul 02 Python
python 定义类时,实现内部方法的互相调用
Dec 25 Python
在Django中预防CSRF攻击的操作
Mar 13 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
python关于倒排列的知识点总结
Oct 13 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 和 COM
2006/10/09 PHP
PHP中一个控制字符串输出的函数
2006/10/09 PHP
source.php查看源文件
2006/12/09 PHP
PHP开发规范手册之PHP代码规范详解
2011/01/13 PHP
php中explode函数用法分析
2014/11/15 PHP
php生成curl命令行的方法
2015/12/14 PHP
PHP文件上传小程序 适合初学者学习!
2019/05/23 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
ajax无刷新动态调用股票信息(改良版)
2008/11/01 Javascript
javascript 按回车键相应按钮提交事件
2009/11/02 Javascript
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
JQuery 插件制作实践 xMarquee插件V1.0
2010/04/02 Javascript
(function($){...})(jQuery)的意思
2010/07/22 Javascript
jQuery的链式调用浅析
2010/12/03 Javascript
node.js中的fs.exists方法使用说明
2014/12/17 Javascript
jQuery使用hide方法隐藏指定元素class样式用法实例
2015/03/30 Javascript
js实现iPhone界面风格的单选框和复选框按钮实例
2015/08/18 Javascript
微信小程序 Audio API详解及实例代码
2016/09/30 Javascript
Vue代码整洁之去重方法整理
2019/08/06 Javascript
HTML+JavaScript实现扫雷小游戏
2019/09/30 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
python统计字符串中指定字符出现次数的方法
2015/04/04 Python
python按照多个条件排序的方法
2019/02/08 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
2020/03/08 Python
Ibatis中如何提高SQL Map的性能
2013/05/11 面试题
生产管理的三大手法
2013/11/11 职场文书
写给女生的道歉信
2014/01/08 职场文书
银行员工职业规划范文
2014/01/21 职场文书
兰兰过桥教学反思
2014/02/08 职场文书
社区文化建设方案
2014/05/02 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
党课主持词大全
2015/06/30 职场文书
python 爬取豆瓣网页的示例
2021/04/13 Python
python 自动刷新网页的两种方法
2021/04/20 Python