Python面向对象
1 面向对象(OOP)基本概念
面向对象编程—Object Oriented Programming
简写OOP
1.1 面向对象基本概念
1.1.1 过程和函数
- 过程是早期的一个编程概念,过程类似于函数,只能执行,但是没有返回结果;
- 函数不仅能执行,还可以返回结果;
1.1.2 面向过程和面向对象基本概念
- 面向过程—怎么做?
- 把完成某一个需求的所有步骤从头到尾逐步实现;
- 根据开发需求,将某些功能独立的代码封装成一个个函数;
- 最后完成代码,顺序的调用不同的函数;
-
面向过程的缺点:
- 例如子函数1需要调用子函数2和n-1,程序相互之间调用关系就变得复杂;
- 或者,子函数n-1的参数发生改变,需要修改所有调用它的函数;
-
面向对象—谁来做?
- 相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
- 1、在完成某一个需求前,首先确定职责—要做的事情(方法);
- 2、根据职责确定不同的对象,在对象内部封装不同的方法(多个);
- 3、最后完成的代码,就是顺序的让不同的对象调用不同的方法;
-
面向对象的特点
- 注重**对象和职责,**不同的对象承担不同的职责;
- 更加适应复杂的需求变化,是专门针对复杂项目开发,提供固定套路;
- 需要在面向过程的基础上,再学习一些面向对象的语法;
1.2 类和对象
- 目标
- 类和对象的概念
- 类和对象的关系
- 类的设计
1.2.1 类和对象的概念
- 类和对象是面向对象编程的两个核心概念
1、类
- 类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用;
- 特征被称为属性;
- 行为被称为方法;
2、对象
1.2.2 类和对象的关系
1.2.3 类的设计
1.3 面向对象基础语法
- 目标
dir
内置函数- 定义简单的类(只包含方法)
- 方法中的
self
参数 - 初始化方法
- 内置方法和属性
1.3.1 dir内置函数
- 在
python
中对象几乎是无所不在的,我们之前学习的变量、数据、函数都是对象;
1.3.2 定义简单的类(只包含方法)
1.3.3 接收对象的变量同样是对对象的引用
-
等号右侧创建对象,等号左侧引用对象;
-
创建多个对象,使用同一个类创建出不同的对象
1.3.4 方法中的self参数
- !!哪一个对象调用的方法,self就是哪一个对象的引用!!
1.3.5 初始化方法_ _init _ _
-
创建对象时,自动调用初始化方法,
def_ _init_ _(self):
-
__init__
方法就是专门用来定义一个类具有哪些属性的方法!
1、在初始化方法内部定义属性
- 在
_ _ init_ _ _
方法内部使用**self.属性名=属性的初始值
,**就可以定义属性; - 定义属性后,再使用Cat类创建的对象,就会拥有该属性;
- 类内部_ _ init__是定义的属性的初始值;
2、利用传入参数设置属性初始值
1.3.6 内置方法和属性_ _ del _ _\ _ _str _ _
1、——del——方法
del
关键字可以删除一个对象- del时就会调用
__ del __
2、——str——方法
- 注意,
__ str __
必须返回一个字符串
2 面向对象封装案例
-
封装
- 1、封装是面向对象编程的一大特点;
- 2、面向对象编程的第一步—将属性和方法封装到一个抽象的类中;
- 3、外界使用类创建对象,然后让对象调用方法;
- 4、对象方法的细节都被封装到类的内部
-
案例一:小明爱跑步
-
提示:
- 1、在对象的方法内部,是可以直接访问对象的属性的;
- 2、同一个类创建的多个对象之间,属性互不干扰;
-
案例二:摆放家具
-
案例三:士兵突击案例
-
可变类型 is ==不相同
-
不可变类型,is ==相同
-
在
python
中针对None比较时,建议使用is
判断;
3 面向对象进阶
3.1 私有属性和私有方法
3.1.1 定义
-
!!在定义属性或方法时,在属性名或方法名前增加两个下划线,定义得就是私有属性或方法!!
-
在对象方法内部,是可以访问对象的私有属性的
3.1.2 伪私有属性和私有方法
- 在python语言中,没有真正意义的私有!!!
3.2 单继承
- 目标
- 单继承
- 多继承
- 面向对象三大特性
- 封装根据职责将属性和方法封装到一个抽象的类中
- 继承实现代码的重用,相同的代码不需要重复的编写
- 多态不同的对象调用相同的方法,产生不同的执行结果,增加代码灵活度
3.2.1 继承的概念语法和特点
- 继承的概念:子类拥有父类的所有方法和属性
3.2.2 方法的重写
- 子类拥有父类的所有方法和属性;
- 子类继承自父类,可以直接享受父类总已经封装好的方法,不需要再次开发;
3.2.3 父类的私有属性和方法
- 子类对象不能在自己的方法内部,直接访问父类的私有属性或私有方法
- 子类对象可以通过父类的公有方法间接访问到私有属性或私有方法
3.3 多继承
3.3.1 概念语法
- 子类可以拥有多个父类,并且具有所有父类的属性和方法
3.3.2 多继承的使用注意事项
3.3.3 Python中的MRO—方法搜索顺序
MRO---method resolution order
,主要用于在多继承时判断方法、属性的调用路径;- 左右————是内置属性,左侧——是私有属性/方法
- 所有创建的类,都是**
class object
的子类;**
3.3.4 新式类与旧式(经典)类object
object
是python
为所有对象提供的基类,提供一些内置的属性和方法,可以使用dir
函数查看
3.4 多态
- 面向对象三大特性
- 1、封装 根据职责将属性和方法封装到一个抽象类中
- 定义类的准则
- 2、继承 实现代码的重用
- 设计类的技巧
- 子类针对自己特有的需求,编写特定的代码
- 3、**多态 **不同的子类对象调用相同的父类方法,产生不同的执行结果
- 多态可以增加代码的灵活度
- 以继承和重写父类方法为前提
- 调用方法的技巧,不会影响到类的内部设计
- 1、封装 根据职责将属性和方法封装到一个抽象类中
3.5 类的结构
3.5.1 术语–实例
-
概念
- 1、创建出来的对象叫做类的实例;
- 2、创建对象的动作叫做实例化;
- 3、对象的属性叫做实例属性;
- 4、对象调用的方法叫做实例方法;
-
结论!!!
- 每一个对象都有自己的独立的内存空间,保存各自不同的属性;
- !!多个对象的方法,在内存中只有一份!!,在调用方法时,需要把对象的引用传递到方法内部
3.5.2 类是一个特殊的对象、
3.5.3 类属性和实例属性
-
1、使用赋值语句,定义类属性,记录
2、属性的获取机制
-
除了使用
类名.属性
访问类属性,还可以使用对象名.类属性
访问,但是不推荐; -
如果使用
对象名.类属性=值
赋值语句,只会给对象添加一个属性,而不会影响到类属性的值;
3.5.4 类方法和静态方法
1、类方法
2、静态方法
- 调用静态方法,不需要创建实例对象,就可以通过**
类名.静态方法
**调用; - 当方法不需要访问实例属性或方法也不需要访问类属性或方法;
3、方法综合案例
4、案例小结
-
1、实例方法-–方法内部需要访问实例属性;
- 实例方法内部可以使用类名.访问类属性
-
2、类方法—方法内部只需要访问类属性;
-
3、静态方法—方法内部,不需要访问实例属性和类属性;
3.6 单例
- 目标
- 单例设计模式
__new__
方法- Python中的单例
3.6.1 单例设计模式
- 设计模式
- 设计模式前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一个特定问题的解决方案;
- 使用设计模式是为了可重用代码,让代码更容易地被他人理解,保证代码可靠性;
- 单例设计模式
- 目的:—让类创建的对象,在系统中只有唯一的一个实例;
- 每一次执行
类名()
返回的对象,内存地址是相同的;
3.6.2 __ new __方法(内置方法)
- 为了修改
__ new __
在创建对象分配空间时,每次都是统一空间地址,就可以达到单例设计模式的目的;
3.6.3 Python中的单例
- 单例—让类创建的对象,在系统中只有唯一的一个实例
1、单例设计模式代码实现
2、只执行一次初始化工作
3.7 异常
- 目标
- 异常的概念
- 捕获异常
- 异常的传递
- 自定义异常
3.7.1 异常的概念
- 程序在运行时,如果**
Python解释器
**遇到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常; - 程序停止执行并且提示错误信息这个动作,通常称之为**:抛出(raise)异常**
- 程序开发时,很难将所有的特殊情况都处理的面面俱到,通过异常捕获可以针对突发事件做集中地处理,从而保证程序的稳定性和健壮性;
3.7.2 捕获异常
3.7.3 错误类型捕获
3.7.4 异常捕获完整语法
3.7.5 异常的传递
- 当函数/方法执行出现异常,会将异常传递给函数/方法的调用一方;
- 如果传递到主程序,仍然没有异常处理,程序才会被终止;
- 为了减轻工作量,不在每个函数中都写异常捕获代码,因此这种异常传递机制就可以解决这个工作量;在主程序中统一捕获异常;
3.7.6 抛出raise异常
1、应用场景
2、抛出异常
def input_pwd():
pwd=input("请输入密码:")
if pwd>=8:
return pwd
print("抛出异常")
#1、创建异常对象
exp=Exception("密码长度不够")
#2、主动抛出异常
raise exp
try:
print(input_pwd())
except Exception as result:
print(result)
3.8 模块
3.8.1 模块基础
- 模块是Python程序架构的一个核心概念;
3.8.2 模块的两种导入方式
-
from...import
之后不需要模块名.的方式,可以直接使用模块提供的工具—全局变量,函数,类; -
同时导入同名函数,后导入模块的函数会覆盖掉先导入的函数;
-
因为Python解释器顺序执行;
3.8.3 模块的搜索顺序
-
会首先搜索当前目录,然后在搜索系统目录,因此,不要与系统模块重名,重名时就只能导入自己的模块而不能导入系统目录下的系统模块;
-
__ file __
内置属性查看导入模块路径
3.8.4 原则—每一个文件都应该是可以被导入的
- 在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍!
- 怎么解决呢?
- 以后要按照这种格式编写代码;方便导入模块;
def main():
pass
#根据内置属性判断是否执行以下代码
if __name__ == "__main__":
main()
3.8.5 包
-
概念
- 包是一个包含多个模块的特殊目录;
- 目录下有一个特殊的文件**
__ init __.py
** - 包名的命名方式和变量名一致,小写字母+_
-
好处
- 使用
import包名
可以一次性导入包中的所有模块
- 使用
-
在外界使用包中的模块,需要在
__ init __.py
中指定对外界提供的模块列表
3.8.6 发布/制作模块
- 制作发布压缩包步骤介绍
(1)创建setup.py
3.8.7 pip安装第三方模块
4 文件
- 目标
- 文件的概念
- 文件的基本操作
- 文件/文件夹的常用操作
- 文本文件的编码方式
4.1 文件的概念
4.2 文件的基本操作
1、操作文件的套路
- 1、打开文件
- 2、读、写文件
- 读,将文件内容读入内存
- 写,将内存内容写入文件
- 3、关闭文件
2、操作文件的函数/方法
3、read方法—读取文件
4、文件指针
- 读不到内容,因为执行过一次read方法后,文件指针移动到读取内容末尾(一般是文件末尾
5、打开文件的方式(Open传递的第二参数)
6、按行读取文件内容
7、文件读写案例—复制文件
- 小文件复制
- 打开一个已有文件,读取完整内容,并写入到另外一个文件
- 打开一个已有文件,读取完整内容,并写入到另外一个文件
- 大文件复制
4.3 文件/目录的常用管理操作
- 在终端/文件浏览器中执行常规的文件/目录管理操作,例如:
- 创建、重命名、删除,改变路径、查看目录内容
- 在
Python
中,如果希望通过程序实现上述功能,需要导入os
模块;
4.4 文本文件的编码格式
- 文本文件存储的内容是基于字符编码的文件,常见的编码有
ASCII
编码,UNICODE
编码等;**Python 2.X
默认使用ASCII
编码;**Python 3.x
默认使用utf-8
编码;
4.5 eval函数