08-Python面向对象-面向对象实践

学习地址:

撩课-Python大数据+人工智能1
撩课-Python大数据+人工智能2
撩课-Python大数据+人工智能3
撩课-Python大数据+人工智能4
撩课-Python大数据+人工智能5
撩课-Python大数据+人工智能6
撩课-Python-GUI编程-PyQt5

1.如何定义一个类?

		class 类名:
        pass

2.怎样通过类,创建出一个对象?

		根据类创建对象
			one = Money()
		执行流程
			1. 类的定义
			2. 根据类,创建出一个对象
			3. 将对象的唯一标识返回

3.属性相关

1).属性和变量的区别及判定依据?
			区别
				概念
					变量是“可以改变的量值”
					属性是“属于某个对象的特性”
				访问权限
					变量:根据不同的位置,存在不同的访问权限
						全局变量
						局部变量
						...
					属性:只能通过对象来进行访问
						所以,必须先找到对象
						对象也是通过变量名来引用;而既然是变量,也有对应的访问权限
			判定依据
				是否存在宿主

2).对象属性

1).怎样让一个对象拥有一些属性?(增)

				1. 直接通过对象,动态添加
					语法:
					对象.属性 = 值
				2. 通过类的初始化方法(构造方法)
					__init__方法

怎样访问一个对象的属性?(查)

				一般访问
					对象.属性
				如果访问不到
					会直接报错
					需要记住错误提示
			怎样修改一个对象的属性?(改)
				同新增一样;系统会自动识别,不存在则新增,存在则修改
				语法
					对象.属性 = 值
			怎样删除一个对象的属性?(删)
				del 对象.属性
			补充:
				查看对象的所有属性?
				对象.__dict__
2).类属性
			万物皆对象,类也是一个对象
				比如,生产月饼的模板,对于月饼来说它是“类”
				但模板本身是不是也是一个具体的东西,也是由其他的东西创建出来的??
			怎样让一个类拥有属性?(增)
				方式1
					类名.类属性 = 值
				方式2
					class Dog:
	dogCount = 0

怎样查询一个类的属性?(查)

				通过类访问
					类名.类属性
				通过对象访问
					对象.类属性
				注意:
					为什么可以通过对象访问到类属性?
					答:和Python对象的属性查找机制有关
						优先到对象自身去查找属性
							找到则结束
						如果没有找到
							则根据__class__找到对象对应的类
							到这个类里面查找

怎样修改一个类的属性?(改)

				通过类名改
					语法如同给类增加一个属性的方式1
						系统也会自动检测
						不存在,则新增
						存在,则修改
					类名.属性 = 值
				能否通过对象改?
					不能!

怎样删除一个类的属性?(删)

				通过类名删除
					del 类名.属性
				能否通过对象删除?
					不能!
					del 语句只删除直系属性
			注意
				类属性的内存存储问题
					一般情况下,属性存储在__dict__的字典当中
						有些内置对象没有这个__dict__属性
					一般对象可以直接修改__dict__属性
					但类对象的__dict__为只读;默认无法修改
						可以通过setattr方法修改
				类属性被各个对象共享
					类属性修改之后,所有的对象访问到的类属性都会跟着修改
			补充
				查看一个类的所有属性
				类名.__dict__

对象属性和类属性之间的区别联系?

			存储不同
			抽象层级不同
			宿主不同
			案例考察
				类
					class Person:
    count = 1
				对象
					p = Person()
				问
					p.count += 1
						代码执行之后
					Person.count 与 p.count 打印的结果分别是多少?
		高级

如何限制对象的属性?

				通过设置类属性:__slots__
				这个属性是一个列表
					列表中的元素,即为通过这个类创建出的对象可以添加的对象属性
					如果这个类实例出的对象,添加了非列表之内的属性,则会报错

4.方法相关

方法的概念

			描述一个目标的行为动作
				比如描述一个人怎样吃,怎样喝,怎样玩...
			和函数非常类似
				都封装了一系列行为动作
				都可以被调用的之后,执行一系列行为动作
				最主要的区别就是:调用方式

方法的划分

			实例方法
				默认第一个参数需要接收到一个实例
			类方法
				默认第一个参数需要接收到一个类
			静态方法
				静静的看着前面俩装逼,第一个参数啥也不默认接收
			注意
				1. 划分的依据是:方法的第一个参数必须要接收的数据类型
				2. 不管是哪一种类型的方法,都是存储在类当中;没有在实例当中的
				3. 不同类型方法的调用方式不同
					但,不管怎么调,把握一个原则
					不管是自己传递,还是解释器帮我们处理;最终要保证不同类型的方法第一个参数接收到的数据,是他们想要的类型
		实例方法
			class Person:
	def run(self):
		pass
			类调用
				注意
					必须传递一个对象,因为实例方法要求呀
			对象调用
				不用手动传,解释器会默认把调用对象本身传递过去
			注意
				一般使用对象来调用
		类方法
			class Person:
	@classmethod
	def countPerson(cls):
		pass
			类调用
				不用手动传递第一个参数,会自动的把调用的类本身给传递过去
			对象调用
				不用手动传递第一个参数,会自动的把调用的对象对应的类给传递过去
			注意
				一般使用类来调用
		静态方法
			class Person:
	@staticemethod
	def countPerson():
		pass
			类调用
				直接调用就可以, 不需要考虑第一个参数
			对象调用
				直接调用就可以
			注意
				具体使用谁来调用,根据场景,哪个比较适合方便就使用哪个

补充

			函数和方法的区别?
				是否有宿主
				函数都是独立的个体,函数之间几乎没有共享的数据
				方法有宿主
			self-注意点
				代表调用的对象
				子主题 2

类相关补充

			元类
				概念
					创建类对象的类
						对象怎样产生的?
							由类创建出来的
						类是不是对象?
							是
						所以,类对象是不是由另外一个类创建出来的?
							是
							元类
					结构图

类对象的创建方式以及创建流程

					创建方式
						通过class 定义
							当我们这么写这个类描述的时候, 解释器会自动的帮我们创建对应的类对象
						通过type函数进行创建
					类的创建流程
						1. 检测类中是否有明确 __metaclass__属性
							有, 则通过指定元类来创建这个类对象
						2. 检测父类中是否存在__metaclass__属性
							有, 则通过指定元类来创建这个类对象
						3. 检测模块中是否存在__metaclass__属性
							有, 则通过指定元类来创建这个类对象
						4. 通过内置的type这个元类,来创建这个类对象
				元类的应用场景
					1)   拦截类的创建
					2)   修改类
					3)   返回修改之后的类
					后面补充
			类的描述
				目的
					方便理清逻辑思路
					方便多人合作开发时的沟通
					方便生成项目文档
					...
				描述方式
					直接在类的下方,使用三个 "双引号"对就可以
					需要注明类的作用, 以及类属性描述
					至于方法, 则直接在方法下,使用三个"双引号"对描述即可
						作用
						参数
						返回值
				生成项目文档(补充)
					方式1
						使用内置模块
							pydoc
						具体步骤
							查看文档描述
								python3 -m pydoc 模块名称
							启动本地服务, 浏览文档
								python3 -m pydoc -p 1234
							生成指定模块html文档
								python3 -m pydoc -w 模块名称
					方式2
						使用三方模块
							Sphinx
							epydoc
							doxygen
						具体步骤
							目前感兴趣了可以先自行研究
							后续讲完"包和模块"之后,会进行补充

属性相关补充

			私有化属性
				概念
					是指将一些原本公开的属性设置权限, 只能小范围访问, 其他地方访问不了
				意义
					保证数据的安全性
					提高代码的可维护性
				注意
					Python并没有真正的私有化支持,但是, 可以使用下划线完成伪私有的效果
					类属性(方法)和实例属性(方法)遵循相同的规则
				x
					公有属性
						类内部访问
						子类内部访问
						模块内其他位置访问
							类访问
								父类
								派生类
							实例访问
								父类实例
								派生类实例
						跨模块访问
							import形式导入
							from 模块 import * 形式导入
				_y
					受保护属性
						类内部访问
						子类内部访问
						模块内其他位置访问
							类访问
								父类
								派生类
							实例访问
								父类实例
								派生类实例
						跨模块访问
							import形式导入
							from module import * 形式导入
								有__all__指明对应变量
								没有__all__指明对应变量
				__z
					私有属性
						类内部访问
						子类内部访问
						模块内其他位置访问
							类访问
								父类
								派生类
							实例访问
								父类实例
								派生类实例
						跨模块访问
							参照单下划线开头变量的访问原则
					私有属性的实现机制
						名字重整(Name Mangling)
							重改__x为另外一个名称, 如
								_类名__x
						目的
							防止外界直接访问
							防止被子类同名称属性覆盖
					应用场景
						数据保护
						数据过滤
				补充
					xx_
						"变量名_" 这个格式是为了与系统属性作区分
					__xx__
						两端__一般为系统内置属性或方法, 所以以后命名注意避免

只读属性

				概念
					一个属性(一般指实例属性), 只能读取, 不能写入
				应用场景
					有些属性, 只限在内部根据不同场景进行修改, 而对外界来说, 不能修改, 只能读取
					比如
						电脑类的网速属性, 网络状态属性
				方式1
					方案
						全部隐藏
							私有化
								既不能读
								也不能写
						部分公开
							公开读的操作
					具体实现
						私有化
							通过"属性前置双下划线"实现
						部分公开
							通过公开的方法
							优化
								property
									作用
										将一些"属性的操作方法"关联到某一个属性中
									概念补充
										经典类
											没有继承(object)
										新式类
											继承(object)
										Python2.x版本定义一个类时, 默认不继承(object)
										Python3.x版本定义一个类时, 默认继承(object)
										建议使用
											新式类
									property
										在经典类中
											只能管理一个属性的读取操作
										在新式类中
											可以管理一个属性的删改查操作
				方式2
					方案
						借助系统内置的方法进行拦截
					具体实现
						__setattr__方法
							当我们使用 "实例.属性 = 值" 这种格式给一个实例增加或修改属性的时候,
							都会调用系统内置的这个方法
							在这个方法的内部, 才会真正的把属性以及对应的值给存储到 __dict__当中
						解决方案
							在这个方法中, 进行拦截
			内置特殊属性
				类属性
					__dict__ : 类的属性
					__bases__ : 类的所有父类构成元组
					__doc__ :类的文档字符串
					__name__: 类名
					__module__: 类定义所在的模块
				实例属性
					__dict__ : 实例的属性
					__class__: 实例对应的类
		方法相关补充
			私有化方法
				私有方法
					def __方法():
	pass
				注意
					不要定义 "_类名__方法名" 这种方法

内置特殊方法

				生命周期方法(下一小节单独介绍)
				其他内置方法
					信息格式化操作
						__str__方法
							作用
								一个对象的描述字符串, 更加方便用户阅读, 对用户更友好
							触发方式
								print 打印一个对象时
								str() 函数时
							格式
								def __str__(self):
	return "描述信息"
						__repr__方法
							作用
								一个对象的描述字符串, 更加方便机器处理, 对机器更友好(开发人员查看)
							触发方式
								当我们在交互模式下, 直接执行某个变量, 就会输出对应信息
								repr() 函数时
							格式
								def __repr__(self):
	return "描述信息"
							注意
								一般情况下, 应满足如下等式
									obj == eval(repr(obj))
								或者描述一个实例详细的信息(类名等等)
					调用操作
						__call__方法
							作用
								使得“对象”具备当做函数,来调用的能力
							使用
								1. 实现实例方法 __call__
								2. 那么创建好的实例, 就可以通过函数的形式来调用
									实例(参数)
							应用场景
								有点类似于之前所讲的"偏函数"的应用场景
								可以将"常变参数"和"不常变参数"进行分离
							案例
								不同类型的笔, 画不同的图形

索引操作

						作用
							可以对一个实例对象进行索引操作
						步骤
							1. 实现三个内置方法
								设置元素的方法
									def __setitem__(self, key, value):
								获取元素的方法
									def __getitem__(self, item):
								删除元素的方法
									def __delitem__(self, key):
							2. 可以以索引的形式操作对象
								增/改
									p[1] = 666
									p["name"] = "sz"
								查
									p["name"]
									p[1]
								删
									del p["name"]
									del p[1]

切片操作

						作用
							可以对一个实例对象进行切片操作
						步骤
							Python2.x
								1. 实现三个内置方法
									__setspice__
										设置某个元素切片时调用
									__getspice__
										获取某个元素切片时调用
									__delspice__
										删除某个元素切片时调用
								2. 可以直接按照切片的方式操作对象
									p[1, 6, 2]
								注意: 过期
							Python3.x
								统一由"索引操作"进行管理
									def __setitem__(self, key, value):
									def __getitem__(self, item):
									def __delitem__(self, key):

比较操作

						作用
							可以自定义对象 "比较大小, 相等以及真假" 规则
						步骤
							实现6个方法
								相等
									__eq__
								不相等
									__ne__
								小于
									__lt__
								小于或等于
									__le__
								大于
									__gt__
								大于或等于
									__ge__

注意

	    如果对于反向操作的比较符, 只定义了其中一个方法,但使用的是另外一比较运算,那么, 解释器会采用调换参数的方式进行调用该方法
								例如
									定义了 "小于" 操作
										x < y
									使用 x > y
										会被调换参数, 调用上面的 "小于操作"
							但是, 不支持叠加操作
								例如
									定义了 "小于" 和 "等于" 操作
									不能使用 x <= y
						    补充
							使用装饰器, 自动生成"反向" "组合"的方法
								步骤
									1. 使用装饰器装饰类
										@functools.total_ordering
									2. 实现
										> 或 >= 或 < 或 <= 其中一个
										实现 ==
							上下文环境中的布尔值
								__bool__

遍历操作

						怎样让我们自己创建的对象可以使用for in 进行遍历?
							实现__getitem__方法
								优先级低
								每次for in 获取数据时, 都会调用这个方法
							或者
							实现__iter__方法
								优先级高
								这个方法, 必须返回一个"迭代器"; 
即, 具备"__iter__"和"__next__"方法
								当for in 遍历这个对象时, 会调用这个__iter__方法返回的迭代器对象的__next__方法
						怎样让我们自己创建的对象可以使用next函数进行访问?
							实现__next__方法
						补充
							1. __iter__方法可以恢复迭代器的初始化值, 复用迭代器
							2. "可迭代" 与 "迭代器"必须实现的方法
							3. iter方法的使用

描述器

						概念
							可以描述一个属性操作的对象
								对象
								属性的操作
									增/改
									删
									查
								描述
						作用
							可以代为管理一个类属性的读写删操作, 在相关方法中, 对数据进行验证处理, 过滤处理等等
							如果一个类属性被定义为描述器,那么以后对这个类属性的操作(读写删), 都将由这个描述器代理
						定义
							定义方式1
								property
							定义方式2
								三个方法
									__get__
									__set__
									__delete__
						调用细节
							使用实例进行调用
								最多三个方法都会被调用
							使用类进行调用
								最多会调用get方法
							不能够顺利转换的场景
								新式类和经典类
									描述器仅在新式类中生效
								方法拦截
									一个实例属性的正常访问顺序
										实例对象自身的__dict__字典
										对应类对象的__dict__字典
										如果有父类, 会再往上层的__dict__字典中检测
										如果没找到, 又定义了__getattr__方法, 就会调用这个方法
									而在上述的整个过程当中, 是如何将描述器的__get__方法给嵌入到查找机制当中?
									就是通过这个方法进行实现
										__getattribute__
										内部实现模拟
											如果实现了描述器方法__get__就会直接调用
											如果没有, 则按照上面的机制去查找

注意

							"资料描述器"和"非资料描述器"
								如果实现了
									_get__
									判定为"非资料描述器"
								如果实现了
									__get__
									__set__
									判定为"资料描述器"
							描述器和实例属性同名时, 操作的优先级问题
								资料描述器 > 实例字典 > 非资料描述器

装饰器

						使用类当做装饰器来使用

猜你喜欢

转载自blog.csdn.net/lkitlike/article/details/85089581
今日推荐