1.1 面向对象基础概念
- python的所有类都继承于最基础的类object
- python语言中数据类型的操作功能都是类方法的体现,
- 它所有数据类型都是对象、函数、模块是对象
OOP(面向对象)的三个基本特征
- 封装:属性和方法的抽象,用数据和操作数据的方法来形成对象逻辑
- 继承:代码复用的高级抽象,用对象之间的继承关系来形成代码复用
- 多态:方法灵活性抽象,让对象的操作更加灵活、更多复用代码
封装
属性的抽象:对类的属性(变量进行定义、隔离及保护)
方法的抽象:对类的方法(函数)j进行定义、隔离及保护
目标是形成一个类对外可操作属性和方法的接口
继承
实现了以类为单位的高抽象级别代码复用
继承是新定义类能够几乎完全使用原有类属性与方法的过程
多态
参数类型的多态:一个方法能够处理多个类型的能力
参数形式的多态:一个方法能够接受多个参数的能力
python天然支持多态不需要支撑的语法
属性:定义在类当中的一种变量(类属性、实例属性)
方法:类方法、实例方法、自由方法、静态方法、保留方法
类对象:维护每个Python类基本信息的数据结构
实例对象:Python类实例后产生的对象,简称对象。
- 类对象全局只有一个,实例对象可以生成多个
- 继承:基类、派生类、子类、父类、超类、重载
- 命名空间:程序元素作用域的表达
- 构造和析构:生成对象和删除对象的过程
1.2 类的构建
类的定义
#类的定义
class <类名>:#建议大写单词组合
[类描述"documentation string"]
<语句块>
- 类定义不限位置,执行时存在即可
- 类定义后通过<类名>._doc_属性访问
- 类定义完成之后默认会生成一个类对象是type类型存储类一些基本信息。
- 类对象内直接包含的语句会被执行,因此,一般不在类定义中直接包含语句。
- 一个类只有一个类对象,可以有很多实例对象。
# 实例对象
<对象名>=<类名>([<参数>])
- 使用
<对象名>.<属性名>()
和<对象名>.<方法名>()
体现类的功能。
构造函数
- 类实例化,接收参数并完成初识操作所用函数
class 类名
def _init_(self,<参数列表>)
语句块
- self参数是本身约定的表类实例自身,继承时传入的时哪个实例就是那个传入的实例
- self表示这个变量是类中的公共变量,告诉其他方法这个是公共的可以随意用。同一个类中调用其他方法要加self
- 构造函数无返回值
类的属性
- 属性是类内部定义的变量
类属性
- 类对象的属性,由所有实例对象所共享,直接定义在类中的属性用
类名.属性名
访问
实例属性
- 实例对象的属性,由各实例对象所独享
- 在类内部,用
self.属性名
访问 - 在类外部,用
对象名.属性名
访问
- 在类内部,用
class 类名
类属性名=类属性初值
def_init_(self,参数列表)
self.实例属性名=实例属性初值#实例属性
# demo
class DemoClass
count=0#类属性
def_init_(self,name,age):
self.name=name#将用户输入的名字赋给name属性
self.age=age
DemoClass.count+=1
#每次生成对象,都会调用_init_方法,每次调用init方法count都会+1
dc1=DemoClass("老王",45)#实例对象
dc1=DemoClass("老李",51)
print("总数:",DemoClass.count)#生成两次对象,故输出 总数:2
print(dc1.name,dc2.name)#输出:老王 老李
类的方法
实例方法
- 实例对象的方法,类内部定义的函数由各实例对象独享,最常用的形式
#类中方法第一个参数是self才可以被实例调用
class 类名:
def 方法名(self,参数列表)
- 使用方式为——>
对象名.方法名(参数列表)
类方法
- 类对象的方法,由所有实例对象共享
- 类方法只能操作类属性和其他类方法,不能操作实例属性和实例方法
- 使用方式为——>
<类名>.<方法名>
或对象名.方法名(参数列表)
class 类名:
@classmethod #此为装饰器,类方法定义所必须
def 方法名(cls,参数列表)#cls表示类对象本身
自由方法
- 类中的一个普通函数,由类所在命名空间管理,类对象独享
class 类名:# 可无参数
def 方法名(参数列表)
- <
类名>.<方法名>
或<类名>.<属性名>
静态方法
- 类中的一个普通函数,由类对象和实例对象共享,仅能操作类属性和其他类方法,不能操作实例属性和实例方法
class 类名:
@staticmethod #此为装饰器,类方法定义所必须
def 方法名(参数列表)
- 使用方式为——>
<类名>.<方法名>
或对象名.方法名(参数列表)
保留方法
- 由双下划线开始和结束的方法,保留使用,如
_len_()
类的析构函数(很少使用)
- 析构函数在
真实删除
实例对象时被调用 - 真实删除:当前对象的引用数为0 或 当前程序退出(垃圾回收)
- 有引用的情况下先删引用
- 一般利用Python垃圾回收机制很少用析构函数
class 类名
def_del_(self)
语句
sys.getrefcount(对象名)
获得引用次数,其返回值为被引用值+1,这个1为其自己
1.3 类的封装
类的属性
公开类属性:即类属性
私有类属性
- 仅供当前类访问的类属性,子类亦不能访问
- 只能在类的内部被方法访问
- 但在类的外部也可以通过
对象名._类名+私有成员
的特殊方式访问
公开实例属性:即实例属性
私有实例属性
- 仅供当前类内部访问的实例属性,子类亦不能访问
- 只能在类的内部被方法访问
- 但在类的外部也可以通过
对象名._类名+私有成员
的特殊方式访问
类的方法
私有方法
- 是类内部定义并使用的函数
输出老王同志 老张同志
保留属性
- 预留的类属性,以双下划线开头和结尾
保留方法
- 预留的类方法,以双下划线开头和结尾
- 具体功能逻辑需要自己写代码完成
1.4 类的继承
类继承的构建
- 派生类只能继承基类的公开属性和方法
- 派生类不能继承基类的私有属性和私有方法
最基础类:object类
-object类为type类型
类的重载
类属性重载
类方法重载
类的多继承
深度优先:基类1-超类,如没有再看基类2
1.5 类的运算
算术运算符的重载
比较运算的重载
第一个true是传统的运算,只要有比较结果就不再往下比较,第二个false是重载后的比较,将其元素和比较
成员运算的重载
其他运算的重载
第一个是传统的,第二个是重载后的
1.6 类的多态
参数类型的多态
可以重载一个几乎要和所有函数类型打交道的Python内部函数,如id函数(任何类型都可以通过id函数获得内部id,可以重载这个函数的运算,使得任何类型都可以返回需要的数据结果)
参数形式的多态
1.7 Python对象的引用
对象是内存区域,引用是指向内存区域的那个地址
赋值仅是复制了一个指针,并且两个指针指向同一个区域。
如整数、字符串为不可变对象
对象的引用为0,则这个对象会被Python的垃圾回收机制清理掉,相关内存会释放
浅拷贝和深拷贝
浅拷贝
for i in [Is,Ia,Ib,Ic]分别代表这四个变量 ,for c in i代表其中的元素,输出其中的元素以及对应的id地址,发现这四个元素的地址没有发生变化,只是这四个容器的地址发生了变化
如上图可知:Is的内存空间中并不包含对象本身,包含的是指向Python字符串的指针和一个指向1,2,3列表的指针,这就是浅拷贝,只拷贝了列表这一层,而没有拷贝列表中元素
如上图,造成的后果。
深拷贝
类的方法引用
1.8 python类的高级话题
命名空间
类的特性装饰器
自定义的异常类型
用as e的方式获得扩展的异常类型的对象,并用这个对象来做相关的操作
类的名称修饰
Python的最小空类