目录
前言多重继承思考片刻总结前言
版本:
(相关资料图)
多重继承
在Python数字比较与类结构中有简略提到类,且在Python中类的mro与继承关系详解稍有解释继承关系,用到一个基类Animal如下:
class Animal:
property_ = "能够思考"
def __init__(self, name, age, value):
self.name_ = name
self.age_ = age
self.val_ = val再定义Action活动作为另一个基类:
class Action:
def __init__(self, action, val):
self.action_ = action
self.val_ = val现在需定义一个Dog类,不仅是动物,还能够跑,可以来继承上面两个类来定义:class Dog(Animal, Action):
def __init__(self, name, age, action, val):
Animal.__init__(self, name, age, val+1)
Action.__init__(self, action, val)
dog = Dog("大福", 8, "跑", 78)
print(dog.__dict__)
# {"name_": "大福", "age_": 8, "val_": 78, "action_": "跑"}发现打印出的实例属性,好像字典的键值更新,先初始化Animal时,val传入的值为79,而后被更新为78,这里为什么不能像继承单个类一样直接用super方法代替呢。
上一篇有提到mro解析顺序,可进行尝试,不重写__init__方法,发现Dog类只能传入三个参数,且都为Animal类的参数,因为继承的两个父类都有该方法,优先继承左边的父类方法,如果想都继承可以考虑这样的形式,然而会提高后续维护的困难性。
可以将最左边的父类改成super方式:
class Dog(Animal, Action):
def __init__(self, name, age, action, val):
super().__init__(name, age, val+1)
Action.__init__(self, action, val)mro解析顺序,与上面所述一致:
Dog.mro() # [__main__.Dog, __main__.Animal, __main__.Action, object]祖孙类
如再进行继承,视Dog为父类,其Animal,Action都为祖父类,定义一个Pet类:
class Pet(Dog):
pass
pet = Pet("大福", 8, "跑", 78)传入参数,和实例化的对象跟Dog一样,如果需要改写某个方法,可以参照之前的方法进行改写,另外若在保留原方法的逻辑上进行补充则用super方法。
Pet类的mro:
Pet.mro() # [__main__.Pet, __main__.Dog, __main__.Animal, __main__.Action, object]
思考片刻
通过上面的继承及对应的mro解析顺序,可以思考以下通过多重继承类后,输出的x属性值为多少:
class Alpha:
def __init__(self, val):
self.x = val
class Beta(Alpha):
pass
class Gamma:
def __init__(self, val):
self.x = val + 1
class Omega(Gamma):
def __init__(self, val):
super().__init__(val + 1)
class Kappa(Beta, Omega):
pass
k = Kappa(1)
print(k.x)如果脑内没有一个mro解析顺序图,这里准备了:
[__main__.Kappa, __main__.Beta, __main__.Alpha, __main__.Omega, __main__.Gamma, object]
这里或许会有疑问,Beta后面不是Omega吗?怎么到Alpha了,可以先看下Omega,继承Gamma,而Gamma跟Alpha并不是同源的,类似于Dog类的继承,那么优先就会使用Alpha的__init__方法,所以在传入参数值1的时候,仅运行了Alpha内的self.x = val,属性x被赋值成1,在最后print输出即为1,打印结果检查:
print(k.x) # 1
若把Gamma类改成继承Alpha类,再次猜测print(k.x)的值为多少?
class Alpha:
def __init__(self, val):
self.x = val
class Beta(Alpha):
pass
class Gamma(Alpha):
def __init__(self, val):
self.x = val + 1
class Omega(Gamma):
def __init__(self, val):
super().__init__(val + 1)
class Kappa(Beta, Omega):
pass
k = Kappa(1)
print(k.x)查看mro解析顺序:
[__main__.Kappa, __main__.Beta, __main__.Omega, __main__.Gamma, __main__.Alpha, object]
此时发现Alpha解析优先级排在最后,Beta跟Omega可以看做是Beta跟Gamma的优先级比较,因为Omega继承Gamma,且重写了__init__方法,所以当传入参数时会对Gamma类的属性进行赋值,虽然Beta类直接继承Alpha,但Gamma类也直接继承,所以Alpha解析顺序需要排在Gamma后面,从而当Kappa类传入参数时,经过Omega的super加1,传入到Gamma处时为:self.x = val + 1中的val为2,输出的k.x的值即为3,查看打印结果:
print(k.x) # 3
总结
通过连续两篇对类继承及mro解析顺序的说明,理解类在多重继承中的变化,无论继承多少遍,总归要回归本心,但也不能胡乱继承,有条理的,有意义的继承,才能让自己乃至他人更好理解当下写出的类。
到此这篇关于Python中类的mro与继承关系详解的文章就介绍到这了,更多相关Python mro内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 2充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 3好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 4名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 5亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 6京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 7网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 8市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 9北京市市场监管局为企业纾困减负保护经济韧性
- 10市场监管总局发布限制商品过度包装标准和第1号修改单

