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