目录
Python Super用法附:super的典型用法总结Python Super用法
这篇文章我们来介绍一下 super,我相信大部分的人使用 super 都是使用这种方式;
# 就是我有一个 class 比如说是 Male,然后继承另外一个 class 比如是 Person,然后我在这个 Male 也就是它的子类的 init 函数里面用 super().__init__() 来调用它父类的初识化函数 from objprint import op class Person: def __init__(self, name): self.name = name class Male(Person): def __init__(self, name): super().__init__(name) self.gender = "male" m = Male("xiaoyang") op(m) # 输出:
在我们常用 super 的时候都通常会认为 super 是一个方法或者函数,但是实际上 super 是一个正儿八经的 class,它是一个内置内的名字,然后 super() 并不是调用了一个函数 ,super() 是建立 了一个 super 的对象
>>> type(super)
尽管我们更常用的是 super() 括号里面什么都没有,但是 super 的完整版它里面应该是有两个参数,第一个参数是一个 type 也就是一个 class,第二个参数是一个 type 或者是一个 object,其中第二个参数决定了这一个函数绑定到那个 object 或者 class 上,同时第二个参数决定了使用那个mro,而第一个参数决定了在 mro 链上 从哪个class 开始往后找,例如;
from objprint import op class Person: def __init__(self, name): self.name = name class Male(Person): def __init__(self, name): # super().__init__(name) super(Male, self).__init__(name) self.gender = "male" m = Male("xiaoyang") op(m) # 输出:# 其实我们看刚才的 super().__init__(name) 它是等价于 super(Male, self).__init__(name) 的。
那么这个super(Male, self)
它是做了这样一个事情,首先它要从 self 这个 object 里面拿到 mro,然后他会找到第一个 argument,也就是 Male 在 mro 里所处的位置,那在当前的情况下 Male 就是最开始的那个(Male Person object)接下来他会从 Male 后面的那个 class 开始找,那它第一个找到的就是 Person,然后它就看Person 里面有没有__init__
这个函数,然后发现有这个函数,然后它在把这个__init__
绑定到 self 上,在这里可以理解为这个 Person 的__init__
函数传进去的这个 self 就是 super 里面的这个 self,也就是说Person.__init__(self,name)
这行代码等价于super(Male, self).__init__(name)
这行代码。
至于为什么不直接使用Person.__init__(self,name)
是有几个原因:
在来看这个示例:
from objprint import op class Animal: def __init__(self, age): self.age = age class Person(Animal): def __init__(self, age, name): super().__init__(age) self.name = name class Male(Person): def __init__(self,age, name): # super(Male, self).__init__(age, name) super(Person, self).__init__(age, name) self.gender = "male" m = Male(18, "xiaoyang") op(m)
如果在 Male 中正常的使用它super(Male, self).__init__(age, name)
,那么它就会正常的初始化所有的东西,它会访问这个 Person 的__init__
,然后 Person 的__init__
会访问 Animal 的__init__
,最后就完成了这个 Male。
那如果把它改成super(Person, self).__init__(age, name)
,那么就会报错,因为当我们使用super(Person, self)
的时候,self 的 mro 链是 Male Person Animal 然后是 object,那第一个参数它由于是 Person,所以他会从 Person 后面的那个 class 也就是 Animal 开始找,那 Animal 是有__init__
函数的,但是 Animal 的__init__
只有一个参数 age,所以当我们传入 age name 的时候那就错了,这时候就只需要将它改成只传进去一个 age 如:super(Person, self).__init__(age)
就可以了,同时也跳过了 Person。
总结 super 的两个参数也就是第一个 type 和第二个 type 或者 object 分别决定了什么:
第一个只决定了在 mro 这个链上从哪里开始找
第二个是决定使用这个函数的对象和 mro
super 并不是只能在 class 里面使用的,它可以在任何一个地方使用,我只要给定 第二个参数 object 或者 class ,在给定第一个参数从哪里开始找,我就能使用它的函数,例如:
# 那这里的话就是从 m 这个 object 的 mro 上寻找 Male 后面开始的 __init__ 函数,这样实际上就找到了 Person 的 __init__ 函数,然后再用 Person 的 __init__ 函数对 m 这个 object 做初始化 from objprint import op class Animal: def __init__(self, age): self.age = age class Person(Animal): def __init__(self, age, name): super().__init__(age) self.name = name class Male(Person): def __init__(self,age, name): super(Person, self).__init__(age) self.gender = "male" m = Male(18, "xiaoyang") op(m) print("----------------------") super(Male, m).__init__(20, "xiaoyang") op(m) # 输出:----------------------
附:super的典型用法
很多人对super直观的理解是,调用父类中的方法:
class A: def test(self): print("A.test") class B(A): def test(self): super().test() print("B.test") b = B() b.test()
执行结果为:
A.test
B.test
从上面的例子看来,super确实可以调用父类中的方法。但是看下面的代码:
class A: def test(self): print("A.test") class TestMixin: def test(self): print("TestMixin.test") super().test() class B(TestMixin, A): def test(self): print("B.test") super().test() b = B() b.test()
打印结果:
B.test
TestMixin.test
A.test
上面的代码先创建B的对象b,然后调用b.test(),但是B的test函数通过super(),会调到第一个父类TestMixin的test函数,因为TestMixin是B的第一个父类。
TestMixin中的test函数中通过super调到了A中的test函数,但是A不是TestMixin的父类。在这个继承体系中,A和TestMixin都是B的父类,但是A和TestMixin没有任何继承关系。为什么TestMixin中的super会调到A中的test函数呢?
总结
到此这篇关于Python中Super用法的文章就介绍到这了,更多相关PythonSuper详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?