面向对象
记录学习
- 面向对象编程
- 基础
- 公有私有
- 继承
- 组合,Mixin
- 魔法函数
- 魔法函数概念
- 构造类魔法函数
- 运算类魔法函数
面向对象概述
- OOP思想
- 把一类动作归为一类
- 对于一个任务,把一个任务先进行分解,分解为一个个模块
- 每个模块又由哪些模块构成
- 常用名词
- OO:面向对象
- OOA:面向对象的分析
- OOD:面向对象的设计
- OOI:面向对象的实现
- OOP:面向对象的编程
类的案例
-
案例 01.py
obj是类的名称
class_name指的是成员的名字
anaconda 的使用
- 是一个虚拟环境管理器
- conda list:显示anaconda 安装的包
- conda env list:显示anaconda的虚拟环境列表
- conda creat -n XXX python= 3.6 XXX是建立的虚拟环境名称 ,版本是3.6
- 这样可以建立一个专门的代码环境,需要在setting环境中找道existing(存在的)环境里面安装
- 在anaconda安装目录下找anaconda3–> envs —> 找到建立的虚拟环境的名称,然后有几个版本的python,都一样
类和对象的成员分析
- 案例 02.py
类的三个特性
- 封装
- 继承
- 多态
封装
- 对象的成员进行访问限制
- 三个级别:
- 公开,public:都可以访问
- 受保护的,protected:
- 私有的,private
- 三个英文不是关键词,
- 判别对象的位置
- 对象内部
- 对象外部
- 子类中
私有
- 最高级别的封装,只能在当前类或者对象中访问
- 在成员前面添加两个下划线即可
-
class student():
name = “name”
名字是公开的
__age = 20
两个下划线把这个age封装
s = student()
print(s.__age)
这条代码会报错,提示你没有__age这个 -
私有不是真私有,是一种成为name mangling的改名策略
-
可以使用print(student.dict)让所有的成员显示出来
-
然后会发现,存在一个 _student__age = 20
-
所以可以使用
- print(s._student__age)
-
即可以使用
对象._类名称__被保护的成员名
-
保护
- 受保护的对象进行一定级别的封装,然后在类或者子类中可以进行访问,外部不可以
- 封装方法:在成员名称前添加一个下划线
公开的
- 队成员没有任何操作,在任何地方都可以使用
继承
-
子类和父类
-
案例 03.py
- 两个类,在想要规定的子类后面括号中添加父类的名称
- 默认的父类是object -
继承的特征
- 所有的类都继承自object
- 子类可以使用父类的所有内容,包括公共的,受保护的,但不能使用私有的
- 子类和父类的成员相同,则优先使用子类成员
- 子类如果想要使用父类的成员并进行扩充,则需要使用特定的格式
- 可以使用 父类名.父类成员(self) 的格式来调用父类成员,也可以是用super().父类成员
案例 03,py
- 可以使用 父类名.父类成员(self) 的格式来调用父类成员,也可以是用super().父类成员
-
继承变量函数的顺序问题
- 优先查找自己的变量
- 没有就查找自己的父类
- 如果构造函数在本类中没有定义,则有限调用父类的构造函数
- 如果父类也没有定义,就往父类的父类上面查找
构造函数
- 一类特殊的函数,在实例化之前就调用的函数–初始化工作
- 相当于在实例化的时候,其实是调用了函数,调用的是构造函数
- 案例 04.py
class.mro (class是类的名称)
- 查询一个类的的父类
单继承与多继承
-
单继承:每个类只能继承一个类
- 传承有序,逻辑清晰
- 功能不能无限扩展,只能在当前唯一的继承链中扩展
-
多继承:每个类允许继承多个类
- 功能扩展非常方便
- 继承关系混乱
-
案例 05.py,多继承
-
菱形继承/钻石继承问题
- 多个子类继承子同一个父亲,这些子类又被同一个类继承,于是继承关系形成一个菱形图谱
- 这种继承方式的顺序(mor顺序)
- 首先是自己,子类
- 然后是父类,父类的顺序按照在括号里的书写顺序
- 在之后是父类的父类
- 直到找到要要找的函数为止
多态
- 一种设计思想
- 多态就是同一个对象在不同情况下有不同的状态出现
- 一种调用方式,不同的执行效果
Mixin 设计模式
- 主要采用多继承方式对类的功能进行扩展
- 进行模块化思想
属性
- 案例 06.py
- 进行类的成员属性描述
- 三种操作:
- get, 获取属性
- set, 修改或者添加属性
- delete, 删除属性的操作
- 使用类的成员描述
- 使用类实现描述器
- 使用属性修饰符
- 使用property函数
- x = property(fget,fset,fdel,doc)
- 里面是3种函数,以及一个doc格式,名字可以自己修改
案例 06.py
常用的类内置属性
- dict :以字典的形式显示类的成员组成
- doc : 获取说明文档,文档是三引号写出来的,必须写在定义类的下面
- name : 获取类的名称,如果在模块中使用,获取模块的名称
- bases : 获取某个类的所有父类,以元组的方式显示
魔术方法
- 不需要人为调用的方法,基本是在特定的时候自动触发
- 魔术方法的统一特征,方法名被前后两个下划线包裹
- 案例 07.py
操作类
- init :构造函数
- new : 对象实例化方法,一般不需要使用
- call : 对象当作函数下使用的时候触发,需要先定义一下
- str : 实例被当作字符串的时候触发
- repr : 返回字符串
描述相关
- set
- get
- delete
属性操作相关
-
getattr : 访问一个不存在的属性时触发
-
setaddr : 对成员属性进行设置的时候触发
- 参数
- self用来获取当前对象,
- 被设置的属性名称,以字符串形式出现
- 需要对属性名称设置的值
- 作用:进行属性设置的时候进行验证或者修改
- 注意:在该方法中不能堆属性直接进行,否则死循环
- 参数
运算操作相关
- gt : 进行大于判断的时候触发的函数
- 参数:
- self
- 第二个参数时第二个对象
- 返回值是可以任意的值,推荐返回bool值
gt(self, 第二个参数)
- 参数:
类和对象的三种方法
案例 08.py
- 实例方法 : 常用方法
- 静态方法 : 不需要实例化,通过类直接访问
- 类方法 : 不需要实例化
- @classmethod
def a(cls):
print(cls)
print(“asdasd”) - @staticmethod
def say():
- @classmethod
属性的三种用法
- 赋值,读取,删除
抽象方法
- 没有具体实现内容的方法成为抽象方法
- 主要是规范子类的行为和接口
- 需要借助abc模块,通常称为ABC类
案例 09.py - 抽象类的使用
- 抽象类里面可以定义具体方法,也可以不定义
- 不允许直接实例化
- 必须继承才能是使用,且继承的子类必须是实现所有的继承来的抽象方法
- 父类的由子类实现,子类实现不了,由子类的子类实现
- 子类没有实现抽线方法,子类的也不能实例化
- 抽象类的主要作用是设定类的标准,以便于开发由统一的规范
这种方法主要是先把我们后面要使用的主要函数标出来,然后后面函数去实现,并且不遗漏
- 一般是绑定类,而不是绑定实例
- 也就是对于一个独立的函数,进行函数赋值把函数绑定到了类里面
- 可以通过这种方法自定义类
- 利用type实现
- 利用MetaClass 元类实现
案例 10.py
- 元类命名用MetaClass结尾来标注元类,并且必须继承自type
class tanMetaClass(type):
def new(cls,name,bases,attrs):
attrs[‘id’]= ‘000001’
return type.__new__.(cls,name,bases,attrs)
# 正常定义一个类
class xiaonan(object,metaclass=tanMetaClass):
pass
xiao = xiaonan()
xiao.id