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()
抱歉,评论功能暂时关闭!