Python面向对象
2022-05-18 14:01:12 0 举报
AI智能生成
Python面向对象
作者其他创作
大纲/内容
面向对象开发实例1
作业
通过组合来构建复杂的对象
作业
Python与设计模式例谈
设计模式
一种高级的软件复用形式
能够很好地指导软件设计过程
是成功的软件设计模式和体系结构
观察者模式
一个持有会改变的数据对象,当其数据变化时,让监听者作出响应
策略模式
让一个对象的某个方法可以随时改变,而不用更改对象
作业
鸭子类型与多态
什么是多态
一种类型具有多种类型的能力
允许不同的对象对同一消息作出灵活的反应
以一种通用的方式对待可使用的对象
非动态语言必须通过继承和接口来实现
Python中的多态
通过继承实现多态(子类可以作为父类使用)
子类通过重载父类的方法实现多态
动态语言与鸭子类型
变量绑定的类型具有不确定性
函数和方法可以接受任何类型的参数
调用方法时不检查提供的参数类型
调用时是否成功由参数的方法和属性确定
调用不成功则抛出错误
Python中不用定义接口
多态的好处
可实现开放的扩展与修改的封闭
使Python更具有灵活性
作业
1.通过继承前面课程作业中定义的盒子(Box)类实现可以相加的盒子类,并定义一个调用让盒了可以相加的函数。
2.通过鸭子类型定义一个杯子类,能够将其实例提供给上题中的函数。使得相加后得到一个容量为两个杯子类的实例容量之和的杯子类实例。
类的继承与方法重载
类的继承是面向对象编程的优点之一
继承的特点
减少代码和灵活定制新类
子类具有父类的属性和方法
子类不能继承父类的私有属性/方法
子类可以添加新的方法
子类可以修改父类的方法
继承的语法
定义类时,在类名后:(继承的类名)
多重继承时,括号中放多个父类名
例子:class MyClass(BaseClass)
重载的语法
直接定义和父类同名的方法
修改父类方法
在重载的方法中调用父类方法
同时添加相应的业务逻辑
多重继承时如何调用父类方法
模拟游戏解析
调用父类的方法super().父类方法名
在父类方法的基础上修改或添加功能
作业
通过继承实现一台可灭菌的洗衣机
修改刚才解析的游戏,为精灵添加能量,并每次相遇时各自损失一定的能量。耗尽后游戏结束。
类的特殊方法
深入理解类
类也是一个对象,但具有创建其自身实例的能力。
类可以和一个变量进行绑定。
你可以为类增加属性。
你可以把它作为函数的参数传递。
元类
类的创建和管理者(type)
所有的类都是元类(type)的实例
类实例化过程
__new__()
__init__()
自定义元类
目的:对其创建的类进行预处理
继承type
定义__new__)()方法
还可以定义__init__()方法
应用元类
Python 3.x
类继承中提供关键字参数:metaclass=元类名
Python 2.x
定义一个模块级变量__metaclass__=元类名
为某个类添加类属性__metaclass__=元类名
构造序列
__len__(self)
__getitem__(self,key)
__setitem__(self,key,value)
__delitem__(self,key)
构造iter
__iter__(self)
__next__(self)
构造可比较类
__lt__()
__le__()
__gt__()
__ge__()
__eq__()
__ne__()
构造可运算类
__add__()
__sub__()
__mul__()
__div__()
作业
1.现在让你来回答什么是类?相信你会给出更好的答案。
2.通过定义元类来实现以其作为元类的类具有主人(owner)类属性
3.为前面课程中的色子类定义方法实现:色子可以迭代、可比较、可进行加、减运算。
类方法、静态方法
静态方法
定义方法
@staticmethod装饰
参数不用self
访问特性
不能引用或访问实例属性
可以通过类.类变量访问类属性
调用方法
可以用类、类实例调用
本质
在类中的一个普通函数而已
使面向对象程序中函数归属于类,易于代码管理
用法
与类相关,但不依赖或改变类与实例
创建不同的实例
把类相关工具方法放入类中
类方法
定义方法
@classmethod
必须提供参数cls
访问特性
不能引用或访问实例属性
调用方法
可以用类、类实例调用
继承特性
继承时,传入的类变量cls是子类,而非父类
用途
与类相关,但不依赖或改变类的实例
工厂方法,创建类实例,完成有关预处理
在类内调用静态方法时不用硬编码类名
作业
编写一个色子类
1.具有6个面,每个面为一种颜色
2.每种颜色代表一个数值(1-6)
3.实现一个通过颜色计算两种其代表数值和的静态方法
4.实现一个类方法(gen_dice)用于产生这个类的实例
课程简介
培训对象
对Python面向对象编程感兴趣
已掌握基础的Python面向过程编程
用Python自主开发大、中型应用系统
有未来从事Python相关开发职业目标的
技能目标
了解面向对象编程的基本知识
掌握Python语言中类的定义与使用方法
掌握Python中类的属性与方法及其应用
掌握Python中类继承与多态、方法重载
会用继承和组合来完成项目的面向对象分析和代码实现
怎样学习
1.掌握Python基本语法及顺序、选择、循环基本程序的编写技能
2.注意掌握面向对象的基础知识
3.听课及时做笔记,供复习
4.课后多做实践,理论联系实际才是最好的学习方式
5.加入一些群、论坛等,帮人解决问题,提升自己
面向对象与面向过程
产生背景
科学计算为目标的必然产物
鸡兔同笼
1.先假设全部为鸡(兔),计算出腿数
2.然后算出腿数量差
3.得出鸡(兔)数量
4.计算出另一种动物的数量
软件应用领域的扩张和系统膨胀之后应运而生
编程方法
自顶向下
自底向上
代码主体结构
程序=数据(变量)+算法(函数/过程)
程序=对象+交互
数据操作主体
由函数/过程进行加工与展现
在对象的方法中加工与展现
模拟方法
通过函数/过程操纵表现世界的数据与状态
把世界描绘成具有主动性的对象之间交互
编程思维
搞清处理数据的步骤
面向对象分析
运行效率
较高
稍低
面向对象入门
对象编程体验
一款简单自动运行小游戏模拟:在一维的地图上,有一只虫子和一只蚂蚁。每一次他们都走过一个-3,-2,2,3个随机单位的距离(选定走法,若达到地图边界则放弃移动)。当蚂蚁、虫子处于同一位置时,蚂蚁吃掉虫子,程序结束。
PO
虫子的初始位置
蚂蚁的初始位置
进入循环(条件为蚂蚁和虫子不在同一位置)
依照规则,蚂蚁和虫子移动位置
直到蚂蚁和虫子走到同一位置,程序结束
OO
游戏中的对象有:地图、虫子、蚂蚁
地图是一维的,只需要记录虫子和蚂蚁的位置
蚂蚁和虫子知道自己的位置
蚂蚁和虫子能按规则移动
定义地图、蚂蚁、虫子三个类
主程序中实例化它们,并通过对象间的交互来完成游戏的模拟
理解对象
对象可以指自然界中的任何事物
计算机为解决某个领域问题所使用的事物(自然界中的事物的模型化)
事物(对象)具有自身的特征或能力
计算机中的对象具有解决问题所需的特征或能力
对象优越性
封装
将模型的特征和能力打包在一起
模型的改变由模型自身来完成,就像自然界的事物一样
隐藏模型的细节,外界只能使用他,而不必/不能改变他
继承
符合自然界的分类规律
快速的代码重用
多态
子类可以继承父类的特征与能力,还可以通过自定义来修改其特征与能力
鸭子类型(duck typing)
组合
一个模型可以由其他的模型组成
定义和使用类
最简类定义
类实例化
类与实例之间关系
定义类就是建立模型(模子/印章)
实例化类就是建立真实事物(产品/印章印出的图案)
有特征和能力的类
特征/属性,是类自身包含或知道的数据
能力,以方法体现,是类具有能动性的体现
实例化步骤
调用__new__()方法创建实例
__new__()方法自动从object继承
调用__init__()方法对其初始化
__init__()方法在类中定义
添加类说明(docstring)
紧跟类名行之后,以三引号包围的字符串
查看类说明
类名.__doc__
help(类名)
新式类与经典类
Python 2.x版本
默认为是经典类
继承object为新式类
Python 3.x版本
统一为新式类不用继承object
区别
经典类继承为深度优先
新式类继承为广度优先
课后思考
类和实例是什么关系?
类的属性和方法分别代表什么?
类实例化的基本步骤是什么?
描述对象的特征
实例属性
类被实例化以后才会具有的属性
一般在__init__()方法中创建并初始化
直接使用即定义:self.<属性名>
引用方法:self.<属性名>
self用来代表类的实例的
类外用实例名.属性名方式定义和引用
相同类的不同实例其实例属性是不相关的
一般不建议在__init__()方法之外中创建和初始化实例属性
一般不推荐类外定义和修改,修改可以单独定义方法
类属性
类定义后就存在,而且不需要实例化
类属性使得相同类的不同实例共同持有相同变量
私有属性
不提供限制属性访问的关键字(无法限制类的各种属性在类外直接访问)
使用__开头的变量名加以标志,只有类对象自己能访问
使用_开头的变量名加以标志,应该只有类对象及其子类能访问(非强制性)
特殊属性
保存对象的元数据
__doc__
__name__
__dict__
__module__
__base__
作业
定义一个类Box,具有实例属性长度(length)、宽度(width)、高度(height)。具有私有属性体积(由长、宽、高计算得来),并且它的每个实例可以知道它被实例化的数量。然后实例化它们五次,并输出每个实例的所有属性。
让对象具有能动性
类的方法的定义
def fun_name(self,...): pass
其中的参数self代表类的实例,在调用方法时由系统自动提供。
方法定义时必须指明self参数
类的方法的调用
与普通的函数调用类似
在类的内部调用:self.<方法名>(参数列表)
在类的外部调用:<实例名>.<方法名>(参数列表)
注:以上两种调用方法中,提供的参数列表中都不用包括self
类内方法相互调用
在一个类的内部方法之间是可以相应调用的
调用方法同上面所述的在类的内部调用方法
构造方法及其作用
构造方法就是前面课程提到和使用的__init__()方法
构造方法的作用就是在类实例化时初始化实例
__init__()方法就是类实例化的第二步自动调用的函数
注意其方法名是固定的,但其参数同普通方法一样,至少应带有self参数
初始化实例包括:定义和初始化实例属性;或调用类的一些方法
构造方法可以带有除self外的其它各种参数(关键字参数、默认参数、用元组收集参数、用字典收集关键字参数等);可以达到在实例化类时,为相应的属性传入指定的值。
提醒
本节课所定义的都是类的实例方法,和实例属性一样,必须进行类实例化之后,才能存在和调用它们。
这里使用的是Python3.x版本,print是一个函数。
作业
修改上次课中定义的类Box,要求其具有:访问私有属性(体积)的方法添加颜色属性(_color)和设置与获取Box的颜色的方法添加打开和关闭盒子(Box)的方法,并且限制Box打开(关闭)之后,再次调用打开(关闭)方法会给予提示;即不能重复打开与关闭。在主程序中实例化并进行测试。
深入类的属性
同名的类属性与实例属性
以实例名.属性名引用时,优先引用实例属性
以类名.属性名引用时,只能引用类属性
属性访问的特殊方法(反射)
提供用字符串来操作类的属性/方法的方式
主要工具函数
hasattr(obj_bame,'属性名')
setattr(obj_name,'属性名',值)
getattr(obj_name,'属性名')
属性包装
将方法包装成属性,以隐藏相关实现。
控制属性的类型或范围
虚拟属性(由其它属性处理后得来)
三种属性操作
可读:@property
可写:@<property-name>.setter
可删:@<property-name>.deleter
描述符
将实现特殊协议方法的类作为另一个类的类属性
用来拦截和控制属性访问并可以重复使用
协议方法
__get__()
__set__()
__delete__()
分类
数据描述符(实现全部协议方法)
非数据描述符(实现部分协议方法)
说明:所有类成员函数都是非数据描述符
同名的实例属性和非数据描述符(以方法为例)访问优先级
注意:只能在新式类中使用
__call__()让类的实例如函数一样可调用
作业
修改上节课的作业中定义的类:1.使用属性包装器将私有属性_color包装为color(可读写)属性2.运用描述符在Box类中创建一个类属性(盒子六面的图案字符,只能为数字1-6)3.为其定义__call__(),当作为函数调用时,返回其体积
0 条评论
下一页