一、property装饰器

应用场景1

当我们需要在类中定义一个属性,他本质是一种方法,但是我们要让他用起来像是一种数据

# 例 人类的BMI会随着身高或者体重的变化而变化,所以我们在每次修改身高体重时BMI都会动态的变化,但是Bmi本身又是一种数据,用起来以数据的方式会更清晰
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('hz',70,1.82)
print(obj.bmi)
>>>21.0

应用场景2

当我们把类中的某个属性隐藏起来后,可以用property给他们关联查看,删除,修改的操作

class People:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self, val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val
def del_name(self):
print('不让删除')
# 通过property的方法给类的name属性关联查看,修改,删除操作(按顺序)
name=property(get_name,set_name,del_name)
obj = People('hz')
print(obj.name)
obj.name = 'lxt'
print(obj.name)
del obj.name

应用场景3(场景2优化)

class People:
def __init__(self, name):
self.__name = name @property
def name(self):
return self.__name @name.setter
def name(self, val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val @name.deleter
def name(self):
print('不让删除') obj = People('hz')
print(obj.name)
obj.name = 'lxt'
print(obj.name)
del obj.name

二、继承介绍

定义

继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,新建的类可称为子类或派生类,父类又可称为基类或超类

继承

优点:解决类与类之间代码冗余

缺点:将类耦合到一起

python支持多继承

优点:最大程度的重用父类的属性

缺点:

1 违背了人的思维习惯:继承表达的是一种‘是’什么的关系

2 代码的可读性变差

3 不建议使用多继承,有可能会引发可恶的菱形问题,扩展性变差

如果真的涉及到一个子类不避免的重用多个父类的属性,应该用Mixins

新式类和经典类

在Python2中有经典类与新式类之分,没有显式地继承object类的类,以及该类的子类,都是经典类,显式地继承object的类,以及该类的子类,都是新式类。而在Python3中,即使没有显式地继承object,也会默认继承该类

1 语法

类是为了减少程序的代码重复,而继承就是为了减少类之间的代码重复

我们要找到类之间的重复关系,就要先抽象出来类的属性,把重复的统一成父类

# 老师和学生都属于人类,可以把他们之间的共同属性提取出来放在人类里,再去继承人类
class People:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex class Student(People):
def __init__(self,name,age,sex,sno):
People.__init__(self,name,age,sex)#继承使用人类的属性
self.sno = sno
def choose_course(self,course_obj):
self.course = course_obj class Teacher(People):
def __init__(self,name,age,sex,sarly,level):
People.__init__(self,name,age,sex)#继承使用人类的属性
self.sarly = sarly
self.level = level
def set_score(self,student_obj,valu):
print(f'{self.name}给{student_obj.name}打分:{valu}')
student_obj.score = valu stu_obj = Student('hz',18,'male',21346)
tea_obj = Teacher('egon',111,'male',2000,10)
tea_obj.set_score(stu_obj,18)
print(stu_obj.score)

2 属性查找

对象的属性查找顺序是:对象本身,类,父类

3 继承的实现原理

3.1 菱形问题

大多数面向对象语言都不支持多继承,而在Python中,一个子类是可以同时继承多个父类的,这固然可以带来一个子类可以对多个不同父类加以重用的好处,但也有可能引发著名的 Diamond problem菱形问题(或称钻石问题,有时候也被称为“死亡钻石”),菱形其实就是对下面这种继承结构的形象比喻

这种继承结构下导致的问题称之为菱形问题:如果A中有一个方法,B和/或C都重写了该方法,而D没有重写它,那么D继承的是哪个版本的方法:B的还是C的?如下所示

class A(object):
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B,C):
pass
obj = D()
obj.test() # 结果为:from B

那么为什么是先继承B呢,想知道这个就必须了解python继承实现的原理

3.2 继承原理

python到底是如何实现继承的呢? 对于你定义的每一个类,Python都会计算出一个方法解析顺序(MRO)列表,该MRO列表就是一个简单的所有基类的线性顺序列表,如下

print(D.mro())
>>>[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。 而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

1.子类会先于父类被检查

2.多个父类会根据它们在列表中的顺序被检查

3.如果对下一个类存在两个合法的选择,选择第一个父类

3.3 深度优先和广度优先

非菱形结构

当我们的继承是非菱形结构时,不管是新式类还是经典类都是按照分支一个一个找下去最后找object

菱形结构

经典类:深度优先,会在检索第一条分支的时候就直接一条道走到黑,即会检索大脑袋(共同的父类)

新式类:广度优先,会在检索最后一条分支的时候检索大脑袋

day29 继承的更多相关文章

  1. day29 Pyhton 面向对象 继承进阶

    一.内容回顾 初识继承 父类\基类\超类 子类\派生类 派生 :派生方法.派生属性 单继承 继承的语法class子类名(父类名) 解决开发中代码冗余的问题 子类继承了父类之后,可以调用父类中的方法 如 ...

  2. day29 元类及异常处理

    元类及异常处理 元类 什么是元类 在python中,一切皆对象,对象是由类产生的,那么类是不是对象呢? 举例: class A: pass print(type(A)) # <class 'ty ...

  3. javaScript的原型继承与多态性

    1.prototype 我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉 ...

  4. JavaScript的继承实现方式

    1.使用call或apply方法,将父对象的构造函数绑定在子对象上 function A(){ this.name = 'json'; } function B(){ A.call(this); } ...

  5. javascript中的继承与深度拷贝

    前言 本篇适合前端新人,下面开始...... 对于前端新手来说(比如博主),每当对js的对象做操作时,都是一种痛苦,原因就是在于对象的赋值是引用的传递,并非值的传递,虽然看上去后者赋值给了前者,他们就 ...

  6. 谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  7. JS继承类相关试题

    题目一: //有关于原型继承的代码如下:function Person(name) {   this.name = name;}Person.prototype = {     getName : f ...

  8. JS继承之寄生类继承

    原型式继承 其原理就是借助原型,可以基于已有的对象创建新对象.节省了创建自定义类型这一步(虽然觉得这样没什么意义). 模型 function object(o){ function W(){ } W. ...

  9. JS继承之借用构造函数继承和组合继承

    根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...

随机推荐

  1. 一文说通Dotnet Core的后台任务

    这是一文说通系列的第二篇,里面有些内容会用到第一篇中间件的部分概念.如果需要,可以参看第一篇:一文说通Dotnet Core的中间件   一.前言 后台任务在一些特殊的应用场合,有相当的需求. 比方, ...

  2. throws,throw,try,catch,finally 分别代表什么 意义?

    Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口. 在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例.当一个方法出现异常后便 抛出一个异 ...

  3. 基于session对象实现简单的购物车应用

    大部分购物网站都会实现购物车的功能,基于session对象的购物车应用可以实现一个用户会话有效期内,用户所选多个商品的存储. 为了实现这样的功能需要编写三个JSP页面,分别是login.jsp.mai ...

  4. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.0)- FlexSPI NOR启动时间(RT1170)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 FlexSPI NOR启动时间. 痞子衡刚刚拿到i.MXRT1170 B0版本的芯片,迫不及待地在上面跑了 ...

  5. Android开发Fragment的使用学习

    基本概念 Fragment是Android3.0(API11)提出的概念,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6.所以在开发中要注意不要导错包 导 ...

  6. vue+ajax的实现

    html <tr> <td>用户名</td> <td id="t01"><input type="text" ...

  7. [ C++ ] 勿在浮沙筑高台 —— 内存管理(18~31p) std::alloc

    部分内容个人感觉不是特别重要,所以没有记录了.其实还是懒 embedded pointers 把对象的前四字节当指针用. struct obj{ struct obj *free_list_link; ...

  8. redis高级命令1

    设置name的过期时间是20秒 redis默认是16个数据库,默认是将数据存储在第0个数据库中 因为默认是0,当你选择其他数据的时候,是没有值的

  9. ThinkPHP5使用PHPExcel实现数据导出功能

    1.将PHPExcel类库文件夹放入extend目录下 2.导出功能实现 public function download(){ if(request()->isPost()){ $val = ...

  10. Springboot 集成 ElasticSearch 踩坑

    这里只涉及到基础使用 导包 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...