pytorch super 的用法

库中的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,

(main.Model’>, , )
按这个顺序是从右至左调用,标准用法是:

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
(, , , , , )

都加super以后每个基类都只调用一次

作者:shiheyingzhe
来源:CSDN
原文:https://blog.csdn.net/shiheyingzhe/article/details/83051471
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(Pytorch学习)