2019/11/14 03-Mixin

多继承最怕遇到菱形,这样二义性是无法拒绝的,所以这时候把它线性化,采用一些方式把它线性化,线性化以后采用遍历树的一种方式遍历,但是更加复杂的情况下,不能解决继承路线的单调性
在这里插入图片描述
用c3算法,在类定义的时候,算出mro,如果单调性有矛盾,这个mro会直接抛出异常,不允许这样的继承方式
在这里插入图片描述
在搜索一个方法的时候,会按照某个顺序来解决,先找谁,后找谁,就靠mro,算出一个继承的顺序
在这里插入图片描述
虽然可以模拟世界,但是也引入了世界的复杂性,python只能动态,不能静态编译,所以出了问题就麻烦,团队引入多继承,这个代码可能就不可控,那么别人根本不能弄清楚里面的继承关系
所以宁愿使用单继承,单继承实在解决不来,再去考虑多继承的问题
python的面向对象,虽然可以多继承,但是由于太灵活,需要把控这个项目,大家守规则
比如使用装饰器,装饰器的原理就是修改原有的一些功能,说白了就是传参的时候有一些要求,没办法传参的时候就需要柯里化一下,这样就把参数提取出来了
装饰器说白了就是动态修改对象属性

要做多继承也要让大家明明白白
在这里插入图片描述
文档有pdf,word等都可以保存内容,但是格式完全不同
打印功能是共同需要的,对于文档 document的基类来讲,他也应该用print

这个打印没必要,就可以用下面的未实现异常,在父类中只定义不实现,这个方法交抽象的方法
在这里插入图片描述
假如定义的word和pdf是第三方的,不能修改
在这里插入图片描述
子类各有各的实现,知道如何打印自己的和格式,所以各自提供了print这样的函数,增加子类,在原有的基础上增强
在这里插入图片描述
比如pdf的打印功能继承不好,就在外面继承一次,这就是ocp原则,继承之后只做少量的修改,就提供了一个更强的功能,不要在第三方库直接修改,继承下来后再做修改

如何使用
在这里插入图片描述
谁缺什么补什么就是了
在这里插入图片描述
这是在传统的面向对象里经常要用的,子类要做增强,继承子类,用覆盖的方式来增强原有的方法
父类知道每个子类都必须有一个print打印方法,所以约定好每个子类必须实现,但是因为python并不强制要求
在这里插入图片描述
这次从word上提供,
但是word本身并没有print方法,文档类定义了未实现报错,python这边的意思是,抽象了print方法,抛出了一个未实现的异常,所谓抽象方法就是不实现的方法
在这里插入图片描述在这里插入图片描述
抽象方法的目的就是告诉所有子类,都必须实现
在这里插入图片描述
在其他语言中,比如c++,凡是子类没有实现方法,都不能实例化,但是python可以在这里插入图片描述
抽象方法是未实现的方法,在python使用抛出未实现异常,可以加括号也可以不加括号,未实现的方法,子类在继承父类之后,未实现方法在python中可以不实现
(但这样不好,其实父类不实现,就是让子类来实现,不实现在调用时出错)

在这里插入图片描述
往往在基类中做这样的事情,一般在父类中使用抽象方法告诉子类在继承之后,应当把未实现的方法都实现了,只不过是约定了一个名字,都叫print,保证名字统一
在这里插入图片描述在这里插入图片描述
print方法算是一种功能
在这里插入图片描述
父类中定义就是,父类未实现,子类都应该实现,但是现在只是某一个子类自己有序列化,所以不需要在父类里定义抽象方法

继承还想要弄一些功能
在这里插入图片描述
然后让pdf和B这两个类实现s1的方法
在这里插入图片描述
假如还有个其他类也想要打印方法,那按照道理就需要加入到document来在这里插入图片描述
假如在父类中不做抽象方法定义,可以在子类中直接添加,但是发现有好几个类需要,这样在这几个类上面再做一个抽象的类,统一定义,让大家都继承自它

缺什么补什么跟装饰器类似(不是一个要用,但是不是一个父类里面,缺什么补什么的情况下能不能用装饰器)
在这里插入图片描述

能不能继承自word类,用装饰器来添加一个打印功能
在这里插入图片描述
就是动态方式把这个类改成跟上面差不多,要为这个类动态注入一个类属性,正好对应一个方法,缺print,就增加一个print
在这里插入图片描述
写一下等价式,要在这个类上给它增加一个类属性,指向一个方法,这个方法覆盖document的print方法
在这里插入图片描述
但是这么写会出问题
在这里插入图片描述
表示31行缺少内容
在这里插入图片描述
str对象没有content
在这里插入图片描述
内建函数已经有print在这里插入图片描述
这个相当于 属性=lambda;lambda里面调用print
在这里插入图片描述
但在这里就有冲突了,就修改成_print
在这里插入图片描述
现在用装饰器,会动态的给这个类注入一个函数,这两行执行完,装饰器就给它动态加了方法,动态注册了一个实例方法
在这里插入图片描述在这里插入图片描述
看一下类字典,原来是没有的,里面有print了在这里插入图片描述
用这样的方式就可以注册成功了
在这里插入图片描述
结果ok了
在这里插入图片描述
用装饰器就能很轻松的为这些类增加方法,为类增加属性,
要反推这个公式

在这里插入图片描述
装饰器可以装饰函数,也可以装饰类,装饰器是一种语法,能让后面的标识符,后面的表达式,可以把下面对应的对象,这个对象有可能是函数,有可能是类,作为第一参数传入进去
在这里插入图片描述
property说的很清楚,用的是init函数,init函数是第一参数把fget送进去,剩下的补缺省值
装饰器想要装饰类和函数随便,计算后把下面的对象当做第一参数传入
在这里插入图片描述

mixin是个类,缺什么混什么,缺什么功能,就用这个类来混进这个功能(比如缺打印功能,给一个类混进来,使用多继承)
在这里插入图片描述
之前是装饰器的方式来为这个类增加功能,不用装饰器是否可以,写成这样
这样也是注入了一个新的方法,只不过没用装饰器,所以只要把本质理解了,怎么写随你

在这里插入图片描述
动态赋值在这里插入图片描述在这里插入图片描述
mixin本意上是混合,混合多个类,继承自一个类,能否继承多个类,这个类想做的就是缺什么混合什么
上面的还是用装饰器,下面的用mixin在这里插入图片描述

可以把类作为一个装饰器,一般习惯如果混入mixin,如果是这个子类,就也加mixin以示警告,表达了使用混合的mixin技术
在这里插入图片描述
下面注释掉
在这里插入图片描述
这是从pdf继承,同时多继承printablemixin,两条路继承,缺什么就靠print补
在这里插入图片描述
继承有pdf,就把pdf所有功能集成下来,还有printablemixin补一个print功能,这个类继承好了,就直接实例化
在这里插入图片描述
告诉你未实现
在这里插入图片描述
未实现说明走到document上了
在这里插入图片描述
把没必要的都缩写起来
在这里插入图片描述
现在是pdfm。print调用的document ,跟继承顺序有关mro,方法的解析顺序

习惯的画法是子类指向父类
mixin简称pm
ppm(printablepdfmixin)继承自p 和pm
左边找不到才去招pm路线,靠c3算法走的,MRO,方法解析顺序

在这里插入图片描述
打印看下mro现在是什么
顺序是先找自己,招完自己找pdf,然后document,然后,printablepdfmixin,所以最后调用的是未实现

在这里插入图片描述
之前是printablepdfmixin在后面
在这里插入图片描述
从现在的理解应该先深度优先,所以这个printablemixin在左边,问这个类有没有print方法,这次就打印出如下结果
在这里插入图片描述
这是使用继承的方式,而且是多继承的方式
再定义一个类,这相当于混进来优先用谁(混进来的能力覆盖所有后面继承的东西)

在这里插入图片描述
大多数情况下mixin写的相对简单,没有init方法,缺什么属性补什么属性,缺什么能力做什么样的改动,有些标准库就用mixin
在这里插入图片描述
这时候打印,就打印出来了在这里插入图片描述
注意继承谁在前谁在后,是靠mro决定的,mro是c3算法,一般是前面的是优先查看的,作为顺序上是在前的
在这里插入图片描述在这里插入图片描述
为了不违反ocp原则,应继承后增加在里面去增强方法
在这里插入图片描述
有的类需要序列化,有的不需要,这时候就出现了继承上的一些问题,不需要的就带着,需要的就自己覆盖一下
A需要几样,B需要几样,这时候怎么自由组合,这时候继承就显得很啰唆,继承的层次太多,相对来讲就比较笨重,所以继承的选择方案不一定是最优的选择方案

在这里插入图片描述在这里插入图片描述在这里插入图片描述
可以用装饰器来灵活添加

还有一种是mixin
在这里插入图片描述
我们要把混进来的mixin类放到前面去,否则不能达到预期的目的
在这里插入图片描述
mixin就是其他类混合进来,同时带来了类的属性和方法。这是多继承的所谓的mro(方法解析顺序)保证的
从这里来看mixin和装饰器效果一样,但是mixin是类,可以继承,但是在装饰器不能
在这里插入图片描述

继承,比如觉得上面的mixin太简单了,格式太单挑,能否做一些增强,
写一个类继承自上一个类

在这里插入图片描述
做一些美化,比如加上表头表尾
在这里插入图片描述
再写一个做一些修改,做一个增强打印
在这里插入图片描述
mixin其实可以继承
在这里插入图片描述
mixin比装饰器的好处就是,可以用一些类的特性,再做继承,再增强在这里插入图片描述
mixin本质上是多继承实现的
mixin体现的是一种组合的设计模式,缺什么补进来,这种组合模式靠多继承来实现,靠mro搜索出的顺序,多继承主要的应用还是mixin

在这里插入图片描述
从设计的模式的角度来说,多组合,少继承,对于ocp如果必须继承,子类要使用这个方法,就需要继承父类的,子类又有个性化的东西,覆盖父类的属性即可,如果不覆盖有自己个性的属性就可以只添加在子类中,只添加特别的属性和方法就ok,你要么覆盖,要么自己独立的添加,因为子类才有

动物类,子类跟父类有所不同,有自己的特征,比如脊椎动物需要有脊椎,每个子类都有自己的特点,所以子类要跟父类不一样,继承的同时把一些不一样的东西表达出来,要么覆盖要么自己独有的
但是有些类需要功能,但这些功能实际上是公用的,这些公用的没必要自己去单独定义,需要就加进来(可以用装饰器,动态添加进去,用mixin来混入也是可以的,mixin一般指混合,指多继承的方式来混合进来一些新的属性方法

从设计模式的角度应该多组合,少继承,如果需要这个能力,这个时候就不要继承,组合在一起,但是不好的地方就是,python的这种组合恰恰是多继承实现
所谓的多继承就是为了重建mro,组合是优于继承的,继承比较麻烦,组合比较轻巧,能组合就组合,尽量少使用继承

在这里插入图片描述
mixin类的使用原则,
不应该显示出现init初始化方法
●Mixin类通常不能独立工作,因为它是准备混入别的类中的部分功能实现(非常简单,只是你缺失的一部分功能,是准备混入这个类,来补充这个功能的)
. Mixin类的祖先类也应是Mixin类
使用时,Mixin类通常在继承列表的第一个位置,例如class Printableword(PrintableMixin, Word): pass

在这里插入图片描述
要写在第一参数上,这就是mro的问题
在这里插入图片描述在这里插入图片描述
如果没什么特别要求用装饰器也可以,用mixin也可以,一个是动态注入,一个是通过继承

继承是否注入了进去,现在字典里能否看到print在这里插入图片描述
注释掉
在这里插入图片描述
现在这个字典是空的,因为都在父类,它不需要有
mixin相当于截胡,告诉类用自己的

在这里插入图片描述在这里插入图片描述
序列化,pickle,message,json
三角形面积用海伦公式, (a+b+c)/2 三条边加起来除以2=周长一半
乘以
P(p-a)(p-b)(p-c),开跟方得到这样一个面积

shape代表基类,说明不管什么都有面积
子类,三角形,矩形,园都继承自shape,shape要求所有子类提供面积的计算
父类可以先把面积什么先定义出来,但是什么具体,有子类来实现,子类要么继承要么覆盖,所以现在父类更像是一个抽象的基类
2.圆类还需要增加一个功能,可以序列化的功能

raise可以抛出异常,计算面积如果没有就是未实现
三角形海伦公式,开个方,return回去即可

在这里插入图片描述
rectangle矩形的就比较简单
在这里插入图片描述
这样就算出来了圆的平方在这里插入图片描述
但是这么使用不太好,别人问面积不太使用方法
改成property

在这里插入图片描述在这里插入图片描述
把继承加上去
在这里插入图片描述
这样写出来就接近我们想要的了在这里插入图片描述
为了好用,使用了属性,但是本质上都是方法在这里插入图片描述
圆形序列化
在这里插入图片描述
序列化,学了三种,pickle(不通用,二进制的),json,msgpack(兼顾效率,占的字节数还很短)

现在都把这个三种序列化满足了

在这里插入图片描述
这个mixin混合类,就混入到,序列化圆的类里在这里插入图片描述
有差异,上面是字典,下面已经是json了
在这里插入图片描述
用msgpack就不一样了
在这里插入图片描述
**到时候会还原成字典,因为你是把字典交给它,它还原字典即可
**

这个也特别适合装饰器
在这里插入图片描述
mixin甚至可以把一个类的所有属性都覆盖掉在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
pop尾部弹出,insert中间插入,remove删除,iternodes迭代所有结点

链表是一个个元素串起来,应该元素有一个东西记录下一个链表的地址,单向列表不可以倒着走,但是一定要知道头在哪里开始在这里插入图片描述

双向链表可以从头开始找到尾巴,从尾巴开始找到开头,每一个元素可以当一个单独对象来对待
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
Cannot destructure property 'Symbol(Symbol.iterator)' of 'item' as it is undefined. TypeError: Cannot destructure property 'Symbol(Symbol.iterator)' of 'item' as it is undefined. at eval (webpack-internal:///./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./node_modules/@jiaminghi/data-view/lib/components/flylineChartEnhanced/src/main.vue?vue&type=script&lang=js&:337:23) at Array.map (<anonymous>) at VueComponent.calcflylinePoints (webpack-internal:///./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./node_modules/@jiaminghi/data-view/lib/components/flylineChartEnhanced/src/main.vue?vue&type=script&lang=js&:335:35) at VueComponent.calcData (webpack-internal:///./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./node_modules/@jiaminghi/data-view/lib/components/flylineChartEnhanced/src/main.vue?vue&type=script&lang=js&:293:7) at VueComponent.onResize (webpack-internal:///./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./node_modules/@jiaminghi/data-view/lib/components/flylineChartEnhanced/src/main.vue?vue&type=script&lang=js&:284:7) at eval (webpack-internal:///./node_modules/@jiaminghi/data-view/lib/mixin/autoResize.js:44:57) at Array.eval (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3008:12) at flushCallbacks (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2936:14)
05-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值