Python中super关键字用法实例分析


Posted in Python onMay 28, 2015

本文实例讲述了Python中super关键字用法。分享给大家供大家参考。具体分析如下:

在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1:

代码段1:

class A:
def __init__(self):
  print "enter A"
  print "leave A"
class B(A):
def __init__(self):
  print "enter B"
  A.__init__(self)
  print "leave B"
>>> b = B()

enter B
enter A
leave A
leave B

即,使用非绑定的类方法(用类名来引用的方法),并在参数列表中,引入待绑定的对象(self),从而达到调用父类的目的。

这样做的缺点是,当一个子类的父类发生变化时(如类B的父类由A变为C时),必须遍历整个类定义,把所有的通过非绑定的方法的类名全部替换过来,例如代码段2,

代码段2:

class B(C):  # A --> C
def __init__(self):
  print "enter B"
  C.__init__(self) # A --> C
  print "leave B"

如果代码简单,这样的改动或许还可以接受。但如果代码量庞大,这样的修改可能是灾难性的。很容易导致修改错误的出现。

因此,自Python 2.2开始,Python添加了一个关键字super,来解决这个问题。下面是Python 2.3的官方文档说明:

super(type[, object-or-type])
Return the superclass of type. If the second argument is omitted the super object
returned is unbound. If the second argument is an object, isinstance(obj, type) 
must be true. If the second argument is a type, issubclass(type2, type) must be 
true. super() only works for new-style classes.
A typical use for calling a cooperative superclass method is:
  class C(B):
    def meth(self, arg):
      super(C, self).meth(arg)
New in version 2.2.

从说明来看,可以把类B改写如代码段3:

代码段3:

class A(object):  # A must be new-style class
def __init__(self):
  print "enter A"
  print "leave A"
class B(C):   # A --> C
def __init__(self):
  print "enter B"
  super(B, self).__init__()
  print "leave B"

尝试执行上面同样的代码,结果一致,但修改的代码只有一处,把代码的维护量降到最低,是一个不错的用法。因此在我们的开发过程中,super关键字被大量使用,而且一直表现良好。

1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象;

2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;

3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;

4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);

5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。

从super关键字的help我们也能看出来。

Help on class super in module __builtin__:
class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |           super(C, self).meth(arg)
 | 
 |  Methods defined here:
.......

从上面也能看出来,super是一个类,而且是__builtin__模块中的。

从上面的描述来看,super主要是用于调用父类的方法。

那么,在2.2之前的方法也能调用。为啥非得用super呢?

这是因为super能够阻止对父类方法的多次调用。

super,改变了父类搜索顺序, 返回的是一个特殊的父类对象
看例子:

class A: pass class B(A): pass class C(A):pass class D(B, C): pass

这是4个类的基本关系。

假如不使用super,让D的对象调用他们共有的一个方法,会2次调用A中这个方法。

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
在Gnumeric下使用Python脚本操作表格的教程
Apr 14 Python
python3序列化与反序列化用法实例
May 26 Python
分享python数据统计的一些小技巧
Jul 21 Python
SQLite3中文编码 Python的实现
Jan 11 Python
Django自定义用户认证示例详解
Mar 14 Python
python实现人民币大写转换
Jun 20 Python
Flask模拟实现CSRF攻击的方法
Jul 24 Python
python3实现猜数字游戏
Dec 07 Python
python networkx 根据图的权重画图实现
Jul 10 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
Nov 11 Python
详解numpy1.19.4与python3.9版本冲突解决
Dec 15 Python
Python中的协程(Coroutine)操作模块(greenlet、gevent)
May 30 Python
Python使用Supervisor来管理进程的方法
May 28 #Python
Python运算符重载用法实例
May 28 #Python
Python smallseg分词用法实例分析
May 28 #Python
Python基于smtplib实现异步发送邮件服务
May 28 #Python
Python使用Scrapy爬取妹子图
May 28 #Python
Python实现统计单词出现的个数
May 28 #Python
Python下载懒人图库JavaScript特效
May 28 #Python
You might like
详细介绍PHP应用提速面面观
2006/10/09 PHP
整合了前面的PHP数据库连接类~~做成一个分页类!
2006/11/25 PHP
CodeIgniter实现从网站抓取图片并自动下载到文件夹里的方法
2015/06/17 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
php session的应用详细介绍
2017/03/22 PHP
PHP实现登录注册之BootStrap表单功能
2017/09/03 PHP
Yii1.1框架实现PHP极光推送消息通知功能
2018/09/06 PHP
用jscript实现新建word文档
2007/06/15 Javascript
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
2016/04/07 Javascript
聊一聊jQuery插件uploadify使用方法
2016/08/24 Javascript
通过修改360抢票的刷新频率和突破8车次限制实现方法
2017/01/04 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
Jquery中attr与prop的区别详解
2017/05/27 jQuery
解决vue router使用 history 模式刷新后404问题
2017/07/19 Javascript
Vue实现自定义下拉菜单功能
2018/07/16 Javascript
微信小程序开发之路由切换页面重定向问题
2018/09/18 Javascript
setTimeout与setInterval的区别浅析
2019/03/23 Javascript
微信小程序实现授权登录
2019/05/15 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
2020/05/10 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
2020/07/22 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
[40:06]DOTA2亚洲邀请赛 4.3 突围赛 Liquid vs VGJ.T 第一场
2018/04/04 DOTA
对Python的多进程锁的使用方法详解
2019/02/18 Python
django 将自带的数据库sqlite3改成mysql实例
2020/07/09 Python
用python写一个带有gui界面的密码生成器
2020/11/06 Python
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
serialVersionUID具有什么样的特征
2014/02/20 面试题
销售人员中英文自荐信
2013/09/22 职场文书
快餐公司创业计划书
2014/04/29 职场文书
工作检讨书怎么写
2014/10/10 职场文书
2014年质量工作总结
2014/11/22 职场文书
巾帼标兵事迹材料
2014/12/26 职场文书
电信营业员岗位职责
2015/04/14 职场文书
会计岗位工作总结
2015/08/12 职场文书