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 相关文章推荐
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
Oct 01 Python
Python通过命令开启http.server服务器的方法
Nov 04 Python
Python numpy实现数组合并实例(vstack,hstack)
Jan 09 Python
利用python如何处理nc数据详解
May 23 Python
python使用循环打印所有三位数水仙花数的实例
Nov 13 Python
利用python如何在前程无忧高效投递简历
May 07 Python
基于python进行抽样分布描述及实践详解
Sep 02 Python
Python3常用内置方法代码实例
Nov 18 Python
pandas实现将日期转换成timestamp
Dec 07 Python
使用python的turtle函数绘制一个滑稽表情
Feb 28 Python
python调用摄像头的示例代码
Sep 28 Python
python 实现IP子网计算
Feb 18 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自定义函数call_user_func和call_user_func_array详解
2011/07/14 PHP
浅谈php中变量的数据类型判断函数
2017/03/04 PHP
Thinkphp开发--集成极光推送
2017/09/15 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
PHP中如何使用Redis接管文件存储Session详解
2018/11/28 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
在线游戏大家来找茬II
2006/09/30 Javascript
jquery特效 幻灯片效果示例代码
2013/07/16 Javascript
ext前台接收action传过来的json数据示例
2014/06/17 Javascript
javascript事件模型实例分析
2015/01/30 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
jquery实现文本框textarea自适应高度
2016/03/09 Javascript
Javascript的动态增加类的实现方法
2016/10/20 Javascript
Angular2学习笔记——详解NgModule模块
2016/12/02 Javascript
微信小程序利用co处理异步流程的方法教程
2017/05/20 Javascript
基于es6三点运算符的使用方法(实例讲解)
2017/10/12 Javascript
vue侧边栏动态生成下级菜单的方法
2018/09/07 Javascript
在React项目中使用Eslint代码检查工具及常见问题
2018/10/10 Javascript
发布Angular应用至生产环境的方法
2018/12/10 Javascript
详解jQuery-each()方法
2019/03/13 jQuery
JavaScript点击按钮生成4位随机验证码
2021/01/28 Javascript
举例讲解Python中的Null模式与桥接模式编程
2016/02/02 Python
Python socket网络编程TCP/IP服务器与客户端通信
2017/01/05 Python
Python简单实现两个任意字符串乘积的方法示例
2018/04/12 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
Python matplotlib通过plt.scatter画空心圆标记出特定的点方法
2018/12/13 Python
在matplotlib的图中设置中文标签的方法
2018/12/13 Python
python实现两个dict合并与计算操作示例
2019/07/01 Python
Python面向对象程序设计之继承、多态原理与用法详解
2020/03/23 Python
Anaconda+VSCode配置tensorflow开发环境的教程详解
2020/03/30 Python
Python识别验证码的实现示例
2020/09/30 Python
外语学院毕业生的自我鉴定
2013/11/28 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
财务会计求职信范文
2015/03/20 职场文书
Python爬虫基础讲解之请求
2021/05/13 Python
Python Pygame实战之塔防游戏的实现
2022/03/17 Python