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的Django中将文件上传至七牛云存储的代码分享
Jun 03 Python
由浅入深讲解python中的yield与generator
Apr 05 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
Jun 07 Python
深入理解Python 关于supper 的 用法和原理
Feb 28 Python
详解python单元测试框架unittest
Jul 02 Python
CentOS下Python3的安装及创建虚拟环境的方法
Nov 28 Python
python实现文本进度条 程序进度条 加载进度条 单行刷新功能
Jul 03 Python
Django 导出项目依赖库到 requirements.txt过程解析
Aug 23 Python
python 通过pip freeze、dowload打离线包及自动安装的过程详解(适用于保密的离线环境
Dec 14 Python
举例讲解Python装饰器
Dec 24 Python
python Scrapy爬虫框架的使用
Jan 21 Python
一篇文章带你了解Python和Java的正则表达式对比
Sep 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
一个自定义位数的php多用户计数器代码
2007/03/11 PHP
简单的PHP缓存设计实现代码
2011/09/30 PHP
php数组函数序列之in_array() 查找数组值是否存在
2011/10/29 PHP
深入密码加salt原理的分析
2013/06/06 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
php实现mysql事务处理的方法
2014/12/25 PHP
PHP实现获取FLV文件的时间
2015/02/10 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
Laravel中的Auth模块详解
2017/08/17 PHP
thinkPHP框架RBAC实现原理分析
2019/02/01 PHP
laravel http 自定义公共验证和响应的方法
2019/09/29 PHP
Prototype Object对象 学习
2009/07/12 Javascript
解决js数据包含加号+通过ajax传到后台时出现连接错误
2013/08/01 Javascript
深入理解JS中的Function.prototype.bind()方法
2016/10/11 Javascript
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
浅谈webpack组织模块的原理
2018/03/10 Javascript
jQuery中常用动画效果函数知识点整理
2018/08/19 jQuery
node错误处理与日志记录的实现
2018/12/24 Javascript
vue实现树形结构样式和功能的实例代码
2019/10/15 Javascript
js实现旋转的星空效果
2019/11/01 Javascript
ckeditor一键排版功能实现方法分析
2020/02/06 Javascript
vue动态合并单元格并添加小计合计功能示例
2020/11/26 Vue.js
Windows下安装Scrapy
2018/10/17 Python
python中字符串数组逆序排列方法总结
2019/06/23 Python
Python爬虫 bilibili视频弹幕提取过程详解
2019/07/31 Python
Django REST Swagger实现指定api参数
2020/07/07 Python
利用python+ffmpeg合并B站视频及格式转换的实例代码
2020/11/24 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
2021/03/03 Python
《大自然的语言》教学反思
2014/04/08 职场文书
纠纷协议书
2014/04/16 职场文书
奥林匹克运动会口号
2014/06/19 职场文书
解除劳动关系协议书2篇
2014/11/28 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android