Python中类的mro与继承关系详解(二)
作者:??宿者朽命??? 发布时间:2022-02-28 07:34:17
前言
版本:
windows 10.0
python 3.8
多重继承
在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
来源:https://juejin.cn/post/7124991737952632839


猜你喜欢
- 本文实例讲述了Python单元测试与测试用例。分享给大家供大家参考,具体如下:单元测试与测试用例简介测试用例是一组单元测试,这些单元测试一起
- 本文实例讲述了Python+Socket实现基于TCP协议的客户与服务端中文自动回复聊天功能。分享给大家供大家参考,具体如下:【吐槽】网上的
- 先看看那种容易被注入的SQL id = 11001 sql = """
- 一、享元模式享元,可理解为 Python 中的元类、最小粒度的类,系统中存在大量的相似对象时,可以选择享元模式提高资源利用率。享元具有两种状
- INSERT、DELETE、UPDATE 三种SQL语句是数据库技术的三大基本语句. 在通常的web开发中对它的处理可以说是无处不在. 如果
- 前言首先来讲一下服务端渲染,直白的说就是在服务端拿数据进行解析渲染,直接生成html片段返回给前端。具体用法也有很多种比如:传统的服务端模板
- 索引相关1. 查询(或更新,删除,可以转换为查询)没有用到索引这是最基础的步骤,需要对sql执行explain查看执行计划中是否用到了索引,
- 1、方法一在使用多线程更新 MongoDB 数据时,需要注意以下几个方面:确认您的数据库驱动程序是否支持多线程。在 PyMongo 中,默认
- 九宫格是一种比较古老的设计,它最基本的表现其实就像是一个三行三列的表格。其实它最初是在window的c/s结构中用得比较多,比如我们经常看到
- 一、状态介绍在了解其他概念之前,我们首先要了解进程的几个状态。在程序运行的过程中,由于 * 作系统的调度算法控制,程序会进入几个状态:就绪,运
- 这个函数是前几年刚流行小偷程序的时候,偶写来用于小偷程序中截取代码的;可能有些朋友在我以前的代码中看见过了,但没有写用法,现在把调用方法及使
- 1、新建独立运行环境,命名为env[root@vultr ~]# mkdir projects # 测试的项目总目录[root@vultr
- 前言注意:网上很多教程说需要在build目录下的dev-server.js文件中配置,但目前最新的vue-cli是没有dev-server.
- 导读排序算法可以称得上是我的盲点, 曾几何时当我知道Chrome的Array.prototype.sort使用了快速排序时, 我的内心是奔溃
- 今天遇到一个问题,原有生产系统正在健康运行,现需要监控一张数据表,当增加数据的时候,给管理员发送邮件。领到这个需求后,有同事提供方案:写触发
- linux下mysql默认是要区分表名大小写的。mysql是否区分大小写设置是由参数lower_case_table_names决定的,其中
- 在数据查询的时候,有完整查询和模糊查询之分.在Access和SQL Server中使用模糊查询有一下几种查询:1.用_通配符查询"
- 自动备份MySQL 5.0有三个方案: 备份方案一: 通过 mysqldump命令,直接生成一个完整的 .sql 文件
- 本文实例讲述了PHP实现的获取文件mimes类型工具类。分享给大家供大家参考,具体如下:<?php/* * Copyright 201
- 随着JS与XHTML的应用普及,越来越多的web界面应用技术出现在网站上,比如我们常见的日历控件,搜索下拉框等,这些web界面应用技术大大的