property 是个用类实现的装饰器
由来将绑定给对象的方法伪装成数据属性
使用property有效地保证了属性访问的一致性。另外property还提供设置和删除属性的功能
class People:
def __init__(self,name,weight,height):
self.name=name
self.weight=weight
self.height=height
@property
def bmi(self):
return self.weight / (self.height**2)
obj=People('lili',75,1.85)
obj.bm
@name.setter
@name.deleter
面向对象三大特性二:
继承:是一种新建类的方式,新建的类可称为子类或者派生类,父类有可称为基类或超类
需要注意的是python支持多继承,新建的类可以继承一个或者多个父类
通过类的内置属性__bases__可以查看类继承的所有父类
ps:在python2中有经典类与新式类之分
经典类:没有继承object的子类以及它的子类
新式类:继承object的子类以及它的子类
object类提供了一些常用内置方法的实现,如用来在打印对象时返回字符串的内置方法__str__
ps2:在py3中没有继承object的类会被默认继承object,所以py3中都是新式类
ps3:python多继承
优点:子类可以同时遗传多个父类的属性,最大限度的重用代码
缺点:违背人类思维习惯继承表达的是一种什么是什么的关系
代码可读性变差
扩展性变差,有可能会引发可恶的菱形问题
不建议直接使用多继承,如果真的涉及到子类不可避免的重用多个父类的属性,应该使用Mixins
为何要用? 用来解决类与类之间代码冗余的问题
如何实现继承?
1.要找出类与类之间的继承关系,需要先抽象,再继承。抽象即总结相似之处,总结对象之间的相似之处得到类,总结类与类之间的相似之处就可以得到父类
2.有了继承关系,对象在查找属性时,先从对象自己的__dict__中找,如果没有则去子类中找,然后再去父类中找
3.父类如果不想让子类覆盖自己的方法,可以采用双下划线开头的方式将方法设置为私有的
单继承查找顺序
多继承查找顺序 多继承带来的菱形问题 object不在菱形范围内
继承原理
python到底是如何实现继承的呢? 对于你定义的每一个类,Python都会计算出一个方法解析顺序(MRO)列表,该MRO列表就是一个简单的所有基类的线性顺序列表
python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。 而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
ps:1.由对象发起的属性查找,会从对象自身的属性里检索,没有则会按照对象的类.mro()规定的顺序依次找下去,
2.由类发起的属性查找,会按照当前类.mro()规定的顺序依次找下去
总结:
多继承到底要不用???
要用,但是规避几点问题
1、继承结构尽量不要过于复杂
2、推荐使用mixins机制:在多继承的背景下满足继承的什么"是"什么的关系
派生与方法重用:子类可以派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父类被查找