本周总结
目录
本周总结
派生方法实战演练
'''因为json的序列化数据是有限的'''
'''
查看dumps源码 注意cls参数 默认传JsonEncoder
查看该类的源码 发现default方法是报错的发起者
编写类继承JSONEncoder并重写default方法 之后调用dumps手动传cls=我们自己写的类
'''
class MyJsonEncoder(json.JSONEncoder):
def default(self, o):
"""
:param o: 接收无法被序列化的数据
:return: 返回可以被序列化的数据
"""
if isinstance(o, datetime.datetime): # 判断是否是datetime类型 如果是则处理成可以被序列化的类型
return o.strftime('%Y-%m-%d %X')
elif isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d')
return super().default(O) # 最后还是调用原来的方法防止一下额外操作没做
res = json.dumps(d, cls=MyJsonEncoder)
print(res)
面向对象三大特性之封装
# 封装:就是将数据和功能'封装'起来
# 隐藏:将数据和功能隐藏起来不让用户直接调用 而是开发一些接口间接调用从而可以在接口内添加额外的操作
# 伪装:将类里面的方法伪装成类里面的数据
'''类的定义阶段 名字前面有两个下划线 那么该名字会被隐藏起来 无法直接访问'''
'''在python中其实没有真正意义上的隐藏 仅仅是换了个名字而已 用_类__名字 可以访问'''
"""
以后我们在编写面向对象代码类的定义时 也会看到很多单下划线开头的名字
表达的意思通常特使不要直接访问 而是查找一下下面可能定义的接口
"""
伪装
@property
# 利用装饰器伪装成数据
# 隐藏看起来像数据,但还是方法不能之间修改
@name.setter # 解决上述问题,可以修改
class Foo:
def __init__(self, val):
self.__NAME = val # 将属性隐藏起来
@property # 隐藏看起来像数据,但还是方法不能之间修改
def name(self):
return self.__NAME
@name.setter # 解决上述问题,可以修改
def name(self, value):
if not isinstance(value, str): # 在设定之前进行类型检查
raise TypeError('%s must be str' % value)
self.__NAME = value # 通过类型检查后,将值value存放到真实的位置self.__NAME
@name.deleter # 删除
def name(self):
raise PermissionError('Can not delete')
f = Foo('jason')
print(f.name)
f.name = 'jason123' # 触发name.setter装饰器对应的函数name(f,'jason123')
print(f.name)
del f.name # 触发name.deleter对应的函数name(f),抛出异常Permissionerror
f.name = 123 # 触发name.setter对应的的函数name(f,123),抛出异常TypeError
面向对象三大特性之多态
多态:一种事物的多种形态
水:液态 固态 气态
动物:人 猫 狗 猪
'''
面向对象中多态意思是 一种事物可以有多种形态 但是针对相同的功能应该定义相同的方法
这样无论我们拿到的是哪个具体的事物 都可以通过相同的方法调用功能
'''
'''
鸭子类型:只要你看上去像鸭子 走路像鸭子 说话像鸭子 那么你就是鸭子
'''
# linux系统
"""
文件 能够读取数据也能够保存数据
内存 能够读取数据也能够保存数据
硬盘 能够读取数据也能够保存数据
......
一切皆文件
"""
'''python永远提倡自由简洁大方 不约束程序员行为 但是多态提供了约束的方法'''
面向对象三大特性之反射
利用字符串操作对象的数据和方法
1.hasattr() 重点
判断对象是否含有某个字符串对应的属性名和方法名
2.getattr() 重点
根据字符串获取对象对应的属性名(值)或方法名(函数体代码)
3.setattr()
根据字符串给对象设置或修改数据
4.delattr()
根据字符串删除对象里面的名字
反射实战案例
1.什么时候应该考虑使用反射 只要需求中出现了关键字
对象...字符串...
2.实战案例
1.模拟cmd终端
2.一切皆对象
# 利用反射保留某个py文件中所有的大写变量名及对应的数据值
面向对象的魔法方法
魔法方法:类中定义的双下方法都称为魔法方法
不需要人为调用 在特定的条件下会自动触发运行
eg:__init__创建空对象之后自动触发给对象添加独有的数据
1.__init__
对象添加独有数据的时候自动触发
'''类名加括号 给对象添加独有数学时自动触发'''
2.__str__
对象被执行打印操作的时候自动触发
'''对象被执行打印操作的时候自动触发 该方法返回什么打印的结果就是什么
并且str返回的结果必须是一个字符串类型数据'''
3.__call__
对象加括号调用的时候自动触发
'''对象加括号调用的时候自动触发 该方法返回什么对象调用之后的返回值是什么'''
4.__getattr__
对象点不存在的名字的时候自动触发
'''对象在查找无法使用的名字时自动触发 该方法返回什么 点不存在的名字就可以得到什么'''
5.__getattribute__
对象点名字就会自动触发 有它的存在就不会执行上面的__getattr__
'''对象在查找名字的时候(无论对错)就会自动触发该方法,这个方法用的很少 一般用getattr'''
6.__setattr__
给对象添加或修改数据的时候自动触发 对象.名字=值
'''当对象执行 对象.名字=值的时候就会自动触发'''
7.__enter__
当对象被当做with上下文管理操作的开始自动触发 并且该方法返回什么 as后面的变量名就会接收到什么
8.__exit__
当对象参与with上下文管理语法运行完毕之后自动触发(子代码结束)
元类简介
结论:我们定义的类其实都是由type产生的>>>:元类(产生类的类)
创建类的两种方式
# 方式一:使用关键字class
# 方拾二:利用元类type type(类名,类的父类,类的名称空间)
cls = type('student', (object), {'name': 'jason'})
'''这两个一样'''
"""
了解知识:名称空间的产生
1.手动写键值对
针对绑定方法不好定义
2.内置方法exec
能够运行字符串类型的代码并产生名称空间
"""
元类定制类的产生行为
"""
推导
对象是由类名加括号产生的 __init__
类是由元类加括号产生的 __init__
"""
'''所有的类必须首字母大写 否则无法产生'''
# 1.自定义元类:继承type的类也称之为元类
# 2.指定类的元类:利用关键字metaclass指定类的元类
元类定制对象的产生行为
"""
推导:
对象加括号会执行产生该对象类里面的 __call__
类加括号会执行产生该类的类里面的 __call__
"""
'''给对象添加独有数据的时候 必须采用关键字参数传参'''
魔法方法之双下new
__new__可以产生空对象
设计模式简介
1.设计模式
前人通过大量的验证创建处理解决一些问题的固定高效方法
2.IT行业
23种
创建型
结构型
行为型
3.单例模式
类加括号无论执行多少次永远只会产生一个对象
目的:
当类中有很多非常强大的方法 我们在程序很多地方都需要使用
如果不做单例 会产生很多无用的对象浪费存储空间、
我们想着使用单例模式 整个程序就用一个对象
单例模式实现的多种方式
class C1:
__instance = None
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def singleton(cls): # 单例的意思
if not cls.__instance:
cls.__instance = cls('jaosn', 18)
return cls.__instance
obj1 = C1.singleton()
obj2 = C1.singleton()
obj3 = C1.singleton()
print(id(obj1), id(obj2), id(obj3)) # 2712128685168 2712128685168 2712128685168
obj4 = C1('kevin', 28)
obj5 = C1('tony', 33)
print(id(obj4), id(obj5)) # 2043671986072 2043671986016
'''当不传入值创建一个新对象时,你调用类创建的对象一直都会是同一个,当你想创建一个新的对象时,则会创建一个新对象'''
pickle序列化模块
(跟dump很像)
优势:能够序列化python中所有的类型
劣势:只能够在python中使用 无法跨语言传输
需求:产生一个对象并保存到文件中 取出来还是一个对象
选课系统需求分析
选课系统
角色:学校 学员 课程 讲师
要求:
1.创建北京、上海两所学校
2.创建linux、python、go 3个课程,linux\py在北京开,go在上海开
3.课程包括 周期、价格,通过学校创建课程
4.通过学校创建班级,班级关联课程、讲师5,创建学员时,选择学校,关联班级
5.创建讲师角色时要关联学校
6.提供三个接口
6.1学员视图,可以注册、交学费、选择班级
6.2讲师视图,讲师可以管理自己的班级,上课时选择班级,查看学员列表,修改所管理的学员成绩
6.3管理视图,创建讲师,创建班级,创建课程
7.上面的操作产生的数据都通过pickle序列化保存到文件里
功能提炼
1.管理员功能
注册功能
登录功能
创建学校
创建课程
创建老师
2.讲师功能
登录功能
选择课程
查看课程
查看学生分数
修改学生分数
3.学生功能
注册功能
登录功能
选择学校
选项课程
查看课程分数
选课系统架构设计
三层架构
与ATM的差异
1.第一层做分层展示,管理员,学生,讲师分开
2.第三层创建models存储所有的类 只有该py文件内的代码有资格调用db_handler