您好,欢迎来到小侦探旅游网。
搜索
您的当前位置:首页python中super()方法的理解

python中super()方法的理解

来源:小侦探旅游网
python中super()⽅法的理解

python中对象⽅法的定义很怪异,第⼀个参数⼀般都命名为self(相当于其它语⾔的this),⽤于传递对象本⾝,有时候还会有⼀个参数cls(相当于类名,当直接调⽤类⽅法的时候使⽤)。python2中super()的⽤法: super(class,self).__init__()python3中super()的⽤法: super().__init__()

在类的继承⾥⾯super()⾮常常⽤, 它解决了⼦类调⽤⽗类⽅法的⼀些问题, ⽗类多次被调⽤时只执⾏⼀次。def super(cls, inst):

mro = inst.__class__.mro() return mro[mro.index(cls) + 1]

当使⽤ super(cls, inst) 时,Python 会在 inst 的类的 MRO 列表上搜索 cls 的下⼀个类。⽽查看inst类的的MRO列表的⽅法就是:类.mro() 或 类.__mro__ 或 inst.__class__.mro()例如:当C是⼀个类的时候,获得⼀个类的MRO的⽅法是C.mro() 或 C.__mro__ 或 C().__class__.mro()

执⾏过程:

当执⾏⽣成D的inst对象的时候,先执⾏Enter D

这个时候D类的MRO列表为[, , , , ]

当执⾏super(D,self) 就是在self对象的类的MRO列表中查找D的下⼀个⽗类。这个self是D类的实例对象inst。

⽽D类中的MRO列表中D的下⼀个⽗类是B。例如:

1、super单继承的时候:

class A:

def __init__(self): self.n = 2 def add(self, m):

print('self is {0} @A.add'.format(self)) self.n += m

class B(A):

def __init__(self): self.n = 3 def add(self, m):

print('self is {0} @B.add'.format(self)) super().add(m) self.n += 3b = B()b.add(2)print(b.n)

结果是什么呢?

为什么是8?

执⾏b.add(2)的时候,执⾏A中的add()函数,执⾏的时候这个时候的self是b这个实例,所以这个self.n是3所以执⾏3+2=5

然后执⾏super的下⼀句5+3=8。2、super多继承的时候

#super的多继承class A:

def __init__(self):

self.n = 2 def add(self, m):

print('self is {0} @A.add'.format(self)) self.n += m

class B(A):

def __init__(self): self.n = 3 def add(self, m):

print('self is {0} @B.add'.format(self)) super().add(m) self.n += 3

class C(A):

def __init__(self): self.n = 4 def add(self, m):

print('self is {0} @C.add'.format(self)) super().add(m) self.n += 4class D(B, C):

def __init__(self): self.n = 5 def add(self, m):

print('self is {0} @D.add'.format(self)) super().add(m) self.n += 5d = D()d.add(2)print(d.n)

这个结果是什么呢?

我认为是5+B.add+C.add+A.add+5=5+3+4+2+5=19看下输出的结果:

执⾏过程是什么样的呢?详细的代码分析如下:

class A:

def __init__(self): self.n = 2 def add(self, m):

print('self is {0} @A.add'.format(self))

self.n += m#第4步执⾏,A.add(2),这个时候self=b,n=5,即n=5+2=7class B(A):

def __init__(self): self.n = 3 def add(self, m):

print('self is {0} @B.add'.format(self))

super().add(m)#第2步执⾏,相当于super(B,d),在d的MRO[D,B,C,A,Object]中B的下⼀个C.add(2),这个时候self=b,n=5 self.n += 3 #第6步执⾏,n=11+3=14class C(A):

def __init__(self): self.n = 4 def add(self, m):

print('self is {0} @C.add'.format(self))

super().add(m)#第3步执⾏,相当于super(C,d),在d的MRO[D,B,C,A,Object]中C的下⼀个A.add(2),这个时候self=b,n=5 self.n += 4 #第5步执⾏,n=7+4=11class D(B, C):

def __init__(self): self.n = 5 def add(self, m):

print('self is {0} @D.add'.format(self))

super().add(m)#第1步执⾏相当于super(D,d)这个时候就会返回在d的MRO[D,B,C,A,Object]中D的下⼀个类B,执⾏B.add(2) self.n += 5 #第7步执⾏,n=14+5=19d = D()

print(d.__class__.mro())#[D, B, C, A,object]d.add(2)print(d.n)

当我们调⽤ super() 的时候,实际上是实例化了⼀个 super 类

在⼤多数情况下, super 包含了两个⾮常重要的信息: ⼀个 MRO 以及 MRO 中的⼀个类。当以如下⽅式调⽤ super 时:super(a_type, obj)

MRO 指的是 type(obj) 的 MRO, MRO 中的那个类就是 a_type , 同时 isinstance(obj, a_type) == True 。当这样调⽤时:super(type1, type2)

MRO 指的是 type2 的 MRO, MRO 中的那个类就是 type1 ,同时 issubclass(type2, type1) == True 。

那么, super() 实际上做了啥呢?简单来说就是:提供⼀个 MRO 以及⼀个 MRO 中的类 C , super() 将返回⼀个从 MRO 中 C 之后的类中查找⽅法的对象。

也就是说,查找⽅式时不是像常规⽅法⼀样从所有的 MRO 类中查找举个例⼦, 有个 MRO:[A, B, C, D, E, object]下⾯的调⽤:super(C, A).add()

super 只会从 C 之后查找,即: 只会在 D 或 E 或 object 中查找 add ⽅法

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- xiaozhentang.com 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务