**
NOTE1
**
OOP-Python面向对象
- Python的面向对象
- 面向对象编程
- 基础
- 公有私有
- 继承
- 组合,Minxi
魔法函数 - 魔法函数概述
- 构造类魔法函数
- 运算类魔法函数
- 面向对象编程
1 面向对象概述(ObjectOriented,OO)
- OOP思想
- 接触到任意一个任务,首先想到的是任务这个世界的构成,由模型构成
- 名词
- OO:面向对象
- OOA:面向对象的分析
- OOD:面向对象的设计
- OOI:面向对象的实现
- OOP:面向对象的编程
- 类和对象的概念
- 类:抽象名词,代表一个集合,共性的事物
- 对象:具象的事物,单个个体
- 类和对象的关系
- 一个抽象,代表一大类事物
- 一个具象,代表一类事物的具体个体
- 类中的内容,应该具有两个内容
- 表明事物的特征,叫做属性(变量)
- 表明事物功能或动作,称为成员方法(函数)
2 类的基本实现
- 类的命名
- 遵守变量命名规范
- 大驼峰
- 尽量避开跟系统命名相似的命名
- 如何声明一个类
- 必须用class关键字
- 类由属性和方法构成,其他不允许出现
- 成员属性定义直接使用变量赋值,如果没有值,使用None
- demo01.py
- 实例化类
- 变量 = 类名() #实例化了的一个对象
- 访问对象成员
- 使用点操作符
obj.成员属性名称
obj.成员方法
- 使用点操作符
- 可以通过默认内置变量检查类和对象的所有成员
- 对象所有成员检查
# dict前后各有两个下划线
obj.dict - 类所有成员
# dict前后各有两个下划线
class_name.dict
- 对象所有成员检查
3 anaconda基本使用
- anaconda主要是一个虚拟环境管理器
- 还是一个安装包管理器
- conda list:显示anaconda安装的包
- conda env list:显示anaconda的虚拟环境列表
4 类和对象的成员分析
- 类和对象都可以存储成员,成员可以归类所有,也可以归对象所有
- 类存储成员时使用的是与类关联的一个对象
- 独享存储成员时存储在当前对象中
- 对象访问一个成员时,如果对象中没有该成员,尝试访问类中的同名成员
- 如果对象中有此成员,一定使用对象中的成员
- 创建对象的时候,类中的成员不会放入对象当中,而是得到一个空对象,没有成员
- 通过对象对类中成员重新赋值或者通过对象添加成员时,对应成员会保存在对象中,
而不会修改原来的类成员
5 关于self
- self在对象的方法中表示当前对象本身,如果通过对象调用一个方法,那么该对象会自动传入
到当前方法的第一个 参数 - self不是关键字,只是一个用于接受对象的普通参数,理论上可以用任何普通变量名代替
- 方法中有self形参的方法成为非绑定类方法,可以通过对象访问;没有self形参的方法成为绑定类
方法,只能通过类访问(类属性和实例属性) - 使用类访问绑定类方法时,如果类方法中需要访问当前类成员,可以用__class__.name来访问
- 鸭子模型
6 面向对象的三大特性
- 封装
- 继承
- 多态
封装
- 对对象成员进行访问限制
- 封装的三个级别:
- 公开:public
- 受保护的:protected
- 私有的:private
- 判别对象位置
- 对象内部
- 对象外部
- 子类中
- 私有
- 私有成员是最高级别的封装,只能在当前类或对象中访问
- 在成员前添加两个下划线即可:
class Person():
# name是共有成员
name = ‘liuying’
# __age是私有成员
__age = 18 - Python的私有不是真私有,是一种改名策略(name mangling),
可以使用_类名__成员名访问
- 受保护的
- 受保护的封装是讲对象成员进行一定级别的封装,在类或者子类中可以访问,
但在外部不可以 - 封装方法:在成员名称前添加一个下划线
- 受保护的封装是讲对象成员进行一定级别的封装,在类或者子类中可以访问,
- 公开的
- 公共的封装实际对成员没有任何限制操作
继承
- 一个类可以获得另外一个类中的成员属性和方法
- 作用:减少代码,增加代码复用功能,可以设置类与类直接的关系
- 父类(基类,超类)与子类(派生类),存在is-a关系
- 继承的特征
- 所有类都继承自object类,
- 子类一旦继承父类,则可以使用父类中除私有成员外的所有内容
- 子类继承父类后,并没有将父类成员完全复制到之类中,而是通过引用
关系访问调用 - 子类中可以定义独有的成员属性和方法
- 子类中定义的成员和父类成员如果相同,则优先使用子类成员
- 子类如果想扩充父类的方法,则可以在定义新方法的同时访问父类成员来
进行代码重用,可以使用父类名.父类成员的格式来调用父类成员,也可以
使用super().父类成员的格式来调用
- 继承变量函数的查找顺序问题
- 优先查找子类变量
- 没有则查找父类
- 构造函数如果本类中没有定义,则自动查找调用父类构造函数
- 如果本类有定义,则不再继续向上查找
- 构造函数
- 是一类特殊的函数,在类进行实例化时第一个被调用,主要工作是初始化
- 如果定义了构造函数,实例化时则使用自己的构造函数
- 如果没定义,则自动查找父类构造函数
-如果子类没定义,父类构造函数带函数,则构造对象是的参数应该按照父类参数构造
- super
- super不是关键字,而是一个类
- 作用是获取MRO列表中的第一个类
- 与父类直接没有任何实质性关系,但通过super可以调用到父类
- 单继承和多继承
- 单继承:每一个类只能继承一个类
- 多继承:每个类允许继承多个类
- 单继承和多继承的优缺点
- 单继承
- 传承有序,逻辑清晰语法简单,隐患少
- 功能不能无限扩展,只能在当前唯一的继承链中扩展
- 多继承
- 类的功能扩展方便
- 继承管理混乱
- 单继承
- 菱形继承/钻石继承
- 多个子类继承于同一个父类,这些子类由被同一个类继承,于是继承关系图形成
一个菱形图谱 - 关于多继承的MRO
- MRO就是多继承中,用于保存继承顺序的一个列表
- Python本身采用C3算法来多继承的菱形继承进行计算的结果
- MRO列表的计算原则:
- 子类永远在父类前面
- 如果多个父类,则根据继承语法中括号内的书写顺序存放
- 如果多个类继承了同一个父类,孙子类中只会选取继承语法括号中第一个
父类的父类
- 构造函数
- 在对象进行实例化的时候,系统自动调用一个函数叫构造函数
- 多个子类继承于同一个父类,这些子类由被同一个类继承,于是继承关系图形成
多态
-
多态就是同一个对象在不同情况下有不同的状态出现
-
多态不是语法,是一种设计思想(在Python中)
-
多态性:一种调用方式,不同的执行效果
-
多态:同一事物的多种形态
-
[多态和多态性]
-
Mixin设计模式
- 主要采用多继承方式对类的功能进行扩展
-
使用多继承语法来实现Mixin
-
使用Mixin实现多继承时:
- 首先他必须表示某单一功能,而不是某个物品
- 职责必须单一,如果有多个功能,则写多个Mixin
- Mixin不能依赖于子类的实现
- 子类即使没有继承这个Mixin类,也能照样工作,只是缺少了某个功能
-
Mixin优点:
- 使用Mixin可以在不对类进行任何修改的情况下,扩充功能
- 可以方便的组织和维护不同功能组件的划分
- 可以根据需要任意调整功能类的组合
- 可以避免创建很多新的类,导致类的继承关系清晰
4 相关函数
- issubclass:检测一个类是否是另一个类的子类
- isinstance:检查一个对象是否是另一个类的实例
- hasattr:检查一个成员是否在对象里
- getattr:
- setattr:
- delattr:
- dir:获取对象的成员列表
5 类的成员描述符(属性)
- 类的成员描述是为了在类中对类的成员属性进行相关操作而创建的一种方式
- get:获取属性的操作
- set:修改或者添加属性的操作
- delete:删除属性的操作
- 如果想使用类的成员描述符,大概有三种方法
-
使用类实现描述qi
-
使用属性修饰符
-
使用property函数
- property(fget, fset, fdel, doc)
-
案例:
class Person():
def fget(self):
return self._name * 2def fset(self, name):
self._name = name.upper()
def fdel(self):
self._name = “Noname”name = property(fget, fset, fdel, “”…")
-
- 无论哪种修饰符都是为了对成员属性进行相应控制
- 类的方式:适合多个类中的多个属性共用一个描述性
- property:适用当前类中使用,可以控制一个类中多个阿胡子那个
- 属性修饰符: 适用于当前类中使用控制一个类中的属性
6 类的内置属性:
__dict__:以字典方式显示类的成员组成
__doc__: 获取类的文档信息
__name__: 获取类的名称,如果在模块中使用,获取模块名称
__bases__: 以元组形式显示父类
7 类的常用魔术方法
- 魔术方法就是不需要认为调用的方法,基本是在特定的时刻自动触发
- 魔术方法的统一特征:方法名前后各有两个下划线
- 操作类
- init:构造函数
- new:对象实例化方法,此魔术方法比较特殊,一般不需要使用
- call:对象当函数使用时触发
- str:当对象被当做字符串使用时触发
- repr:返回字符串(和str的区别)
- 描述符相关
- set:
- get:
- delete:
- 属性操作相关:
- getattr:访问一个不存在的属性时触发
- setattr: 对成员属性进行设置时触发
- 参数:
- self用来获取当前对象
- 被设置的属性名称,以字符串形式出现
- 需要对属性名称设置的值
- 作用:进行属性设置的时候进行验证或者修改
- 注意:在该方法终不能对属性进行直接赋值操作,否则死循环,需要对其父类进行赋值
- 参数:
- 运算分类相关魔术方法:
- gt:进行大于判断时触发
- 参数
- self
- 第二个参数是第二个对象
- 返回值可以是任意值,推荐返回布尔值
- 参数
- gt:进行大于判断时触发
8 类和对象的三种方法(注意三种方法区别)
- 实例方法:
- 需要实例化对象才能使用的方法,使用过程中可能需要截止对象的其他对象的方法完成
- 静态方法:
- 不需要实例化,通过直接访问
- 类方法:
- 不需要实例化
10 抽象类
- 抽象方法:没有具体实现内容的方法称为抽象方法
- 抽象方法主要意义是规范了子类的行为和接口
- 抽象类的使用需要借助abc模块
- 抽象类:包含抽象方法的类,通常称为ABC类
- 抽象类的使用
- 抽象类可以包含抽象方法,也可以包含具体方法
- 抽象类中可以有方法,也可以有属性
- 抽象类不允许直接实例化
- 必须继承才可以使用,且继承的子类必须实现所有继承来的抽象方法
- 假定子类没有实现所有继承的抽象方法,则子类也不能实例化
- 抽象类的主要作用是设定类的标准,以便于开发是具有统一的规范
11 自定义类
- 是一个类定义和各种方法的自由组合
- 可以自定义类和函数,然后直接赋值
- 借助MethodType实现
- 使用前需导入types模块
- 可以给实例绑定方法,但对另一个实例不起作用
- instance.func_name = MethodType(function, instance)
- 借助于type实现
- 利用元类实现:MetaClass
- 元类是类
- 用来创建其他的类
- 元类必须以MetaClass结尾:Class PersonMetaClass()
slots
- 作用:限制class实例能添加的属性
-slots = (‘name’, ‘age’) # 用tuple定义允许绑定的属性名称 - 定义的class属性仅在当前类实例中起作用,在继承的子类中不起作用。