Pytorch安装和super类

安装到官网根据要求运行相应的命令https://pytorch.org/get-started/locally/

例:Stable(稳定版)、Windows、Conda(anaconda版本)、Python3.6、None(没有GPU即CPU版本)
打开cmd依次运行命令即可

conda install pytorch-cpu -c pytorch
pip3 install torchvision

库中的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 '__main__.Model'>, <class 'torch.nn.modules.module.Module'>, <class 'object'>)

按这个顺序是从右至左调用,标准用法是:

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
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

如果需要更改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
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

扫描二维码关注公众号,回复: 3677665 查看本文章

加上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
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

 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
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)

这里的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
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)

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

参考的内容:https://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html
                      https://docs.python.org/3.6/library/functions.html?highlight=super#super

猜你喜欢

转载自blog.csdn.net/shiheyingzhe/article/details/83051471