库中的torch.nn.Module模块,声明继承Model类时有提示可以按照这样方式书写
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
其中的super类的作用是继承的时候,调用含super的各个的基类__init__函数,如果不使用super,就不会调用这些类的__init__函数,除非显式声明。而且使用super可以避免基类被重复调用。
使用 print(Model.mro)打印搜索顺序或者祖先树,被官方称为MRO即Method Resolution Order,
(
按这个顺序是从右至左调用,标准用法是:
class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)
super的典型用法:
在具有单一继承结构的类层级中,super可以指代父类而不需要显式的声明,这对更改父类的时候是有帮助的;
在动态执行环境中支持多继承协作,这个功能是python独有的,使得有可能解决菱形图问题,指多个基类实现相同的方法。
先看第一个用法:
class A():
def fortest(self):
print('Call class A')
print('Leave class A')
class B(A):
def fortest(self):
print('Call class B')
A.fortest(self)
print('Leave class B')
sample=B()
sample.fortest()
print(B.__mro__)
运行的结果:
Call class B
Call class A
Leave class A
Leave class B
(, , )
如果需要更改B的基类A为D,那么不仅需要更改声明class B(D),函数体中的函数也要进行更改,如果调用A的地方多,修改起来就会很麻烦,加上super就简单很多
class A():
def fortest(self):
print('Call class A')
print('Leave class A')
class B(A):
def fortest(self):
print('Call class B')
super(B,self).fortest()#等同于super().fortest()
print('Leave class B')
sample=B()
sample.fortest()
print(B.__mro__)
运行的结果:
Call class B
Call class A
Leave class A
Leave class B
(, , )
加上super以后,修改基类就只需要修改声明,不需要修改函数体内的东西,所以super可以指代父类而不需要显式的声明,这对更改基类的时候是有帮助的,使得代码更容易维护
接着看另外的用法:
class A():
def __init__(self):
print('Call class A')
print('Leave class A')
class B(A):
def __init__(self):
print('Call class B')
print('Leave class B')
class C(A):
def __init__(self):
print('Call class C')
super(C,self).__init__()
print('Leave class C')
class D(A):
def __init__(self):
print('Call class D')
super(D, self).__init__()
print('Leave class D')
class E(B,C):
def __init__(self):
print('Call class E')
B.__init__(self)
C.__init__(self)
print('Leave class E')
sample=E()
print(E.__mro__)
运行的结果:
Call class E
Call class B
Leave class B
Call class C
Call class A
Leave class A
Leave class C
Leave class E
(, , , , )
B和C类都继承的A,但是由于B没有使用super,这里调用B的时候没有调用A,只有C自动调用了A
class A():
def __init__(self):
print('Call class A')
print('Leave class A')
class B(A):
def __init__(self):
print('Call class B')
print('Leave class B')
class C(A):
def __init__(self):
print('Call class C')
super(C,self).__init__()
print('Leave class C')
class D(A):
def __init__(self):
print('Call class D')
super(D, self).__init__()
print('Leave class D')
class E(B,C,D):
def __init__(self):
print('Call class E')
B.__init__()
C.__init__()
D.__init__()
print('Leave class E')
sample=E()
print(E.__mro__)
运行的结果:
Call class E
Call class B
Leave class B
Call class C
Call class D
Call class A
Leave class A
Leave class D
Leave class C
Call class D
Call class A
Leave class A
Leave class D
Leave class E
(, , , , , )
这里的A和D都重复调用了一次,尤其是调用C的时候,也调用了D
class A():
def __init__(self):
print('Call class A')
super(A, self).__init__()
print('Leave class A')
class B(A):
def __init__(self):
print('Call class B')
super(B,self).__init__()
print('Leave class B')
class C(A):
def __init__(self):
print('Call class C')
super(C,self).__init__()
print('Leave class C')
class D(A):
def __init__(self):
print('Call class D')
super(D, self).__init__()
print('Leave class D')
class E(B,C,D):
def __init__(self):
print('Call class E')
super(E, self).__init__()
print('Leave class E')
sample=E()
print(E.__mro__)
运行结果是:
Call class E
Call class B
Call class C
Call class D
Call class A
Leave class A
Leave class D
Leave class C
Leave class B
Leave class E
(, , , , , )
作者:shiheyingzhe
来源:CSDN
原文:https://blog.csdn.net/shiheyingzhe/article/details/83051471
版权声明:本文为博主原创文章,转载请附上博文链接!