python类中super()和__init__()的区别

作者:mrr 时间:2021-04-17 16:03:02 

单继承时super()和__init__()实现的功能是类似的


class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'creat A ',
Base.__init__(self)
class childB(Base):
def __init__(self):
print 'creat B ',
super(childB, self).__init__()
base = Base()
a = childA()
b = childB()

输出结果:


Base create
creat A Base create
creat B Base create

区别是使用super()继承时不用显式引用基类。

super()只能用于新式类中

把基类改为旧式类,即不继承任何基类


class Base():
def __init__(self):
print 'Base create'

执行时,在初始化b时就会报错:


super(childB, self).__init__()
TypeError: must be type, not classobj

super不是父类,而是继承顺序的下一个类

在多重继承时会涉及继承顺序,super()相当于返回继承顺序的下一个类,而不是父类,类似于这样的功能:


def super(class_name, self):
mro = self.__class__.mro()
return mro[mro.index(class_name) + 1]

mro()用来获得类的继承顺序。

例如:


class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
# Base.__init__(self)
super(childA, self).__init__()
print 'leave A'
class childB(Base):
def __init__(self):
print 'enter B '
# Base.__init__(self)
super(childB, self).__init__()
print 'leave B'
class childC(childA, childB):
pass
c = childC()
print c.__class__.__mro__

输出结果如下:


enter A
enter B
Base create
leave B
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

supder和父类没有关联,因此执行顺序是A —> B—>—>Base

执行过程相当于:初始化childC()时,先会去调用childA的构造方法中的 super(childA, self).__init__(), super(childA, self)返回当前类的继承顺序中childA后的一个类childB;然后再执行childB().__init()__,这样顺序执行下去。

在多重继承里,如果把childA()中的 super(childA, self).__init__() 换成Base.__init__(self),在执行时,继承childA后就会直接跳到Base类里,而略过了childB:


enter A
Base create
leave A
(<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)

从super()方法可以看出,super()的第一个参数可以是继承链中任意一个类的名字,

如果是本身就会依次继承下一个类;

如果是继承链里之前的类便会无限递归下去;

如果是继承链里之后的类便会忽略继承链汇总本身和传入类之间的类;

比如将childA()中的super改为:super(childC, self).init(),程序就会无限递归下去。

如:


File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
super(childC, self).__init__()
RuntimeError: maximum recursion depth exceeded while calling a Python object

super()可以避免重复调用

如果childA基础Base, childB继承childA和Base,如果childB需要调用Base的__init__()方法时,就会导致__init__()被执行两次:


class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
Base.__init__(self)
print 'leave A'
class childB(childA, Base):
def __init__(self):
childA.__init__(self)
Base.__init__(self)
b = childB()

Base的__init__()方法被执行了两次


enter A
Base create
leave A
Base create

使用super()是可避免重复调用


class Base(object):
def __init__(self):
print 'Base create'
class childA(Base):
def __init__(self):
print 'enter A '
super(childA, self).__init__()
print 'leave A'
class childB(childA, Base):
def __init__(self):
super(childB, self).__init__()
b = childB()
print b.__class__.mro()
enter A
Base create
leave A
[<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]

以上所述是小编给大家介绍的python类中super()和__init__()的区别,网站的支持!

标签:python,super,init
0
投稿

猜你喜欢

  • FileSystem对象常用的文件操作函数有哪些?

    2009-11-01 15:11:00
  • SQL语句练习实例之五 WMS系统中的关于LIFO或FIFO的问题分析

    2011-11-03 16:59:59
  • python matplotlib绘图,修改坐标轴刻度为文字的实例

    2023-09-29 12:27:57
  • PyQt+socket实现远程操作服务器的方法示例

    2022-07-19 01:56:13
  • python实现连连看游戏

    2021-12-02 00:25:10
  • 关于python简单的爬虫操作(requests和etree)

    2022-01-08 02:17:27
  • django+celery+RabbitMQ自定义多个消息队列的实现

    2021-01-21 16:52:10
  • 为什么首页最后设计

    2009-07-17 19:03:00
  • python中matplotlib的颜色及线条控制的示例

    2023-11-04 08:11:50
  • Python发送form-data请求及拼接form-data内容的方法

    2022-11-14 09:55:15
  • 《web信息架构》——分类方式

    2009-11-27 19:16:00
  • Python NumPy教程之数据类型对象详解

    2022-03-29 09:05:19
  • ASP中Global.asa使用方法说明

    2007-11-03 13:18:00
  • django在接受post请求时显示403forbidden实例解析

    2021-12-19 22:41:27
  • Python的Flask框架中实现分页功能的教程

    2022-02-22 04:41:09
  • Python装饰器实现方法及应用场景详解

    2022-04-30 22:57:49
  • 最全的MYSQL备份方法

    2009-12-29 10:19:00
  • Python中的np.random.seed()随机数种子问题及解决方法

    2023-01-15 20:14:02
  • PHP5.6读写excel表格文件操作示例

    2023-11-21 15:03:21
  • Python实现将一个正整数分解质因数的方法分析

    2021-01-09 10:39:29
  • asp之家 网络编程 m.aspxhome.com