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 相关文章推荐
pandas.DataFrame 根据条件新建列并赋值的方法
Apr 08 Python
python3 unicode列表转换为中文的实例
Oct 26 Python
pycharm远程开发项目的实现步骤
Jan 20 Python
使用Python向C语言的链接库传递数组、结构体、指针类型的数据
Jan 29 Python
一步步教你用python的scrapy编写一个爬虫
Apr 17 Python
pandas如何处理缺失值
Jul 31 Python
Python之数据序列化(json、pickle、shelve)详解
Aug 30 Python
Django3.0 异步通信初体验(小结)
Dec 04 Python
如何利用pygame实现简单的五子棋游戏
Dec 29 Python
Tensorflow训练MNIST手写数字识别模型
Feb 13 Python
Python如何省略括号方法详解
Mar 21 Python
Python多线程 Queue 模块常见用法
Jul 04 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.MVC的模板标签系统(二)
2006/09/05 PHP
php学习笔记 数组的常用函数
2011/06/13 PHP
分享下PHP register_globals 值为on与off的理解
2013/09/26 PHP
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
PHP中获取时间的下一周下个月的方法
2014/03/18 PHP
Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
2016/03/21 PHP
详解Yii2 定制表单输入字段的标签和样式
2017/01/04 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
jquery实现table鼠标经过变色代码
2013/09/25 Javascript
json中换行符的处理方法示例介绍
2014/06/10 Javascript
javascript框架设计读书笔记之模块加载系统
2014/12/02 Javascript
基于jQuery实现选项卡效果
2017/01/04 Javascript
基于jQuery实现简单人工智能聊天室
2017/02/10 Javascript
Vue.js bootstrap前端实现分页和排序
2017/03/10 Javascript
AngularJs用户输入动态模板XSS攻击示例详解
2018/04/21 Javascript
详解小程序原生使用ES7 async/await语法
2018/08/06 Javascript
在Vue 中使用Typescript的示例代码
2018/09/10 Javascript
Vue props 单向数据流的实现
2018/11/06 Javascript
[00:32]2018DOTA2亚洲邀请赛Newbee出场
2018/04/03 DOTA
linux系统使用python监测网络接口获取网络的输入输出
2014/01/15 Python
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
Python教程之全局变量用法
2016/06/27 Python
Python BS4库的安装与使用详解
2018/08/08 Python
对Python的多进程锁的使用方法详解
2019/02/18 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
国际知名军事风格休闲装品牌:Alpha Industries(阿尔法工业)
2017/05/24 全球购物
英语师范专业毕业生自荐信
2013/09/21 职场文书
班级学习计划书
2014/04/27 职场文书
幼儿园教研活动总结
2014/04/30 职场文书
个人工作主要事迹
2014/05/08 职场文书
争先创优公开承诺书
2014/08/30 职场文书
甲乙双方合作协议书
2014/10/13 职场文书
开展警示教育活动总结
2015/05/09 职场文书
MySQL 那些常见的错误设计规范,你都知道吗
2021/07/16 MySQL
Redis过期数据是否会被立马删除
2022/07/23 Redis
Win10鼠标宏怎么设置?win10系统鼠标宏的设置方法
2022/08/14 数码科技