Python中的super()方法详解-Python教程

资源魔 27 0

1、独自挪用父类的办法

需要:编写一个类,而后再写一个子类进行承继,应用子类去挪用父类的办法1。

应用办法1打印: 瘦子老板,来包槟榔。

那末先写一个瘦子老板的父类,执行一下:

class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开端被挪用')
        self.name = name
        print('FatFather的name是%s' % self.name)
        print('FatFather的init挪用完结')
def main():
    ff = FatFather("瘦子老板的父亲")

运转一下这个瘦子老板父类的结构办法init 以下:

if __name__ == "__main__":
    main()
FatFather的init开端被挪用
FatFather的name是瘦子老板的父亲
FatFather的init挪用完结

好了,那末上面来写一个子类,也就是瘦子老板类,承继下面的类。

# 瘦子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开端被挪用')
        self.name = name
        print('挪用FatFather类的name是%s' % self.name)
        print('FatFather的init挪用完结')
# 瘦子老板类 承继 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('瘦子老板的类被挪用啦!')
        self.hobby = hobby
        FatFather.__init__(self, name)  # 间接挪用父类的结构办法
        print("%s 的喜好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("瘦子老板的父亲")
    fatboss = FatBoss("瘦子老板", "打架田主")

正在这下面的代码中,我应用FatFather.init(self,name)间接挪用父类的办法。

运转后果以下:

if __name__ == "__main__":
    main()
瘦子老板的类被挪用啦!
FatFather的init开端被挪用
挪用FatFather类的name是瘦子老板
FatFather的init挪用完结
瘦子老板 的喜好是 打架田主

2、super() 办法根本概念

除了了间接应用 FatFather.init(self,name) 的办法,还能够应用super()办法来挪用。

那末起首需求看super()办法的形容以及语法了解一下super() 办法的应用。

2.1 形容

super() 函数是用于挪用父类(超类)的一个办法。

super 是用来处理多重承继成绩的,间接用类名挪用父类办法正在应用单承继的时分没成绩,然而假如应用多承继,会触及到查找程序(MRO)、反复挪用(钻石承继)等种种成绩。

MRO 就是类的办法解析程序表, 其实也就是承继父类办法时的程序表。

相干保举:《Python视频教程》

2.2 语法

如下是 super() 办法的语法:

super(type[, object-or-type])

参数

type -- 类

object-or-type -- 类,普通是 self

Python3.x 以及 Python2.x 的一个区分是: Python 3 能够应用间接应用 super().xxx 替代 super(Class, self).xxx :

Python3.x 实例:

class A:
    pass
class B(A):
    def add(self, x):
        super().add(x)

Python2.x 实例:

class A(object):   # Python2.x 记患上承继 object
    pass
class B(A):
    def add(self, x):
        super(B, self).add(x)

2.3 单承继应用super()

应用super() 办法来改写方才瘦子老板承继父类的 init 结构办法

# 瘦子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开端被挪用')
        self.name = name
        print('挪用FatFather类的name是%s' % self.name)
        print('FatFather的init挪用完结')
# 瘦子老板类 承继 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('瘦子老板的类被挪用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 间接挪用父类的结构办法
        super().__init__(name)
        print("%s 的喜好是 %s" % (name, self.hobby))
def main():
    #ff = FatFather("瘦子老板的父亲")
    fatboss = FatBoss("瘦子老板", "打架田主")

从下面应用super办法的时分,由于是单承继,间接就能够应用了。

运转以下:

if __name__ == "__main__":
    main()
瘦子老板的类被挪用啦!
FatFather的init开端被挪用
挪用FatFather类的name是瘦子老板
FatFather的init挪用完结
瘦子老板 的喜好是 打架田主

那末为何说单承继间接应用就能够呢?由于super()办法假如多承继的话,会触及到一个MRO(承继父类办法时的程序表) 的挪用排序成绩。

上面能够打印一下看看单承继的MRO程序(FatBoss.mro)。

# 瘦子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开端被挪用')
        self.name = name
        print('挪用FatFather类的name是%s' % self.name)
        print('FatFather的init挪用完结')
# 瘦子老板类 承继 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('瘦子老板的类被挪用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 间接挪用父类的结构办法
        super().__init__(name)
        print("%s 的喜好是 %s" % (name, self.hobby))
def main():
    print("打印FatBoss类的MRO")
    print(FatBoss.__mro__)
    print()
    print("=========== 上面依照 MRO 程序执行super办法 =============")
    fatboss = FatBoss("瘦子老板", "打架田主")

下面的代码应用 FatBoss.mro 能够打印出 FatBoss这个类通过 python解析器的 C3算法较量争论当时的承继挪用程序。

运转以下:

if __name__ == "__main__":
    main()
打印FatBoss类的MRO
(<class '__main__.FatBoss'>, <class '__main__.FatFather'>, <class 'object'>)
=========== 上面依照 MRO 程序执行super办法 =============
瘦子老板的类被挪用啦!
FatFather的init开端被挪用
挪用FatFather类的name是瘦子老板
FatFather的init挪用完结
瘦子老板 的喜好是 打架田主

从下面的后果 (<class 'main.FatBoss'>, <class 'main.FatFather'>, <class 'object'>) 能够看出,super() 办法正在 FatBoss 会间接挪用父类是 FatFather ,以是单承继是没成绩的。

那末假如多承继的话,会有甚么成绩呢?

2.4 多承继应用super()

假定再写一个瘦子老板的女儿类,以及 瘦子老板的妻子类,此时女儿需求同时承继 两个类(瘦子老板类,瘦子老板妻子类)。

由于瘦子老板有一个喜好,瘦子老板的妻子需求干活干家务,那末女儿需求帮手同时统筹。

此时女儿就是需求承继应用这两个父类的办法了,那末该若何去写呢?

上面来看看完成代码:

# 瘦子老板的父类
class FatFather(object):
    def __init__(self, name, *args, **kwargs):
        print()
        print("=============== 开端挪用 FatFather  ========================")
        print('FatFather的init开端被挪用')
        self.name = name
        print('挪用FatFather类的name是%s' % self.name)
        print('FatFather的init挪用完结')
        print()
        print("=============== 完结挪用 FatFather  ========================")
# 瘦子老板类 承继 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby, *args, **kwargs):
        print()
        print("=============== 开端挪用 FatBoss  ========================")
        print('瘦子老板的类被挪用啦!')
        #super().__init__(name)
        ## 由于多承继通报的参数纷歧致,以是应用没有定参数
        super().__init__(name, *args, **kwargs)
        print("%s 的喜好是 %s" % (name, hobby))
        print()
        print("=============== 完结挪用 FatBoss  ========================")
# 瘦子老板的妻子类 承继 FatFather类
class FatBossWife(FatFather):
    def __init__(self, name, housework, *args, **kwargs):
        print()
        print("=============== 开端挪用 FatBossWife  ========================")
        print('瘦子老板的妻子类被挪用啦!要学会干家务')
        #super().__init__(name)
        ## 由于多承继通报的参数纷歧致,以是应用没有定参数
        super().__init__(name, *args, **kwargs)
        print("%s 需求干的家务是 %s" % (name, housework))
        print()
        print("=============== 完结挪用 FatBossWife  ========================")
# 瘦子老板的女儿类 承继 FatBoss FatBossWife类
class FatBossGril(FatBoss, FatBossWife):
    def __init__(self, name, hobby, housework):
        print('瘦子老板的女儿类被挪用啦!要学会干家务,还要会帮瘦子老板斗田主')
        super().__init__(name, hobby, housework)
def main():
    print("打印FatBossGril类的MRO")
    print(FatBossGril.__mro__)
    print()
    print("=========== 上面依照 MRO 程序执行super办法 =============")
    gril = FatBossGril("瘦子老板", "打架田主", "拖地")

运转后果以下:

if __name__ == "__main__":
    main()
打印FatBossGril类的MRO
(<class '__main__.FatBossGril'>, <class '__main__.FatBoss'>, <class '__main__.FatBossWife'>, 
<class '__main__.FatFather'>, <class 'object'>)
=========== 上面依照 MRO 程序执行super办法 =============
瘦子老板的女儿类被挪用啦!要学会干家务,还要会帮瘦子老板斗田主
=============== 开端挪用 FatBoss  ========================
瘦子老板的类被挪用啦!
=============== 开端挪用 FatBossWife  ========================
瘦子老板的妻子类被挪用啦!要学会干家务
=============== 开端挪用 FatFather  ========================
FatFather的init开端被挪用
挪用FatFather类的name是瘦子老板
FatFather的init挪用完结
=============== 完结挪用 FatFather  ========================
瘦子老板 需求干的家务是 拖地
=============== 完结挪用 FatBossWife  ========================
瘦子老板 的喜好是 打架田主
=============== 完结挪用 FatBoss  ========================

从下面的运转后果来看,我特意给每一个类的挪用开端和完结都进行打印标识,能够看到。

每一个类开端挪用是依据MRO程序进行开端,而后一一进行完结的。

另有就是因为由于需求承继没有同的父类,参数纷歧定。

以是,一切的父类都应该加之没有定参数*args , **kwargs ,否则参数不合错误应是会报错的。

3、留意事项

·super().init绝对于类名.init,正在单承继上用法根本无差。

·但正在多承继上有区分,super办法能保障每一个父类的办法只会执行一次,而应用类名的办法会招致办法被执行屡次,能够测验考试写个代码 来看输入后果。

·多承继时,应用super办法,对父类的传参数,应该是因为python中super的算法招致的缘由,必需把参数全副通报,不然会报错。

·单承继时,应用super办法,则不克不及全副通报,只能传父类办法所需的参数,不然会报错。

·多承继时,绝对于应用类名.init办法,要把每一个父类全副写一遍, 而应用super办法,只要写一句话便执行了全副父类的办法,这也是为 何多承继需求全副传参的一个缘由。

4、操练

如下的代码的输入将是甚么? 说出你的谜底并诠释。

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print(Parent.x, Child1.x, Child2.x)
1 1 1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
1 2 1

留意:Child1曾经领有了属于本人的x

Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
3 2 3

以上就是Python中的super()办法详解的具体内容,更多请存眷资源魔其它相干文章!

标签: Python python教程 python编程 python使用问题 super()

抱歉,评论功能暂时关闭!