Python之旅的第27天(复习、习题实现、__enter__、__exit__)
最近工作开始有点忙了,感觉晚上学这个,白天工作精神还是不够用,今天正好是周五就看的少一点准备早点睡觉。晚上大致想了一下之前那个选课习题的思路,如果按照编程规范进行操作,还是需要一些思路的,大致目前的分析如下吧!
一、习题实现逻辑
先来个框架:
三个视图:学员视图 讲师视图 管理视图 三个视图即为三个管理接口
五个角色:学校、学员、课程、讲师、班级
五个角色即需要定义5个类 把要求对应成自己看懂的话:
① 创建北京、上海 2 所学校 分析:定义学校类,通过类去创建学校实例
② 创建linux , python , go 3个课程 ,linux\py 在北京开,go 在上海开 分析:定义课程类,通过课程类去创建课程实例
③ 课程包含,周期,价格,通过学校创建课程 分析:课程类里要包含周期、价格 课程实例通过学校类去创建
④ 班级关联课程、班级关联讲师 分析:可以创建班级的时候需输入关联的课程,创建讲师的时候需输入关联的班级;一个班级对应一个课程 一个班级对应一个讲师
⑤ 通过学校创建班级, 班级关联课程、讲师 分析:跟④一样
⑥ 创建学员时,选择学校,关联班级 分析:定义学员类,创建时选择学校,选择班级,通过学校类创建学员实例,班级类里面要有包含学员的信息的字典
⑦ 创建讲师角色时要关联学校 分析:之前一样,依然通过学校类去创建讲师实例
⑧ 学员视图 可以注册, 交学费, 选择班级 分析:看⑥ 学员选择班级后,通过班级关联的课程,打印课程的学费
⑨ 讲师视图, 讲师可以.....bala....bala 分析:讲师视图登录需要讲师名,通过讲师名可以找到对应的班级实例,班级实例里包含班级名,课程名,学员信息等 注:一个班级对应一个课程 一个班级对应一个讲师
一个课程可有多个班级
一个讲师可教授多个班级
一个学员可学习多个班级的课 分析下管理视图:
管理视图具有的功能创建讲师, 创建班级,创建课程,这些都是通过学校创建(即通过学校类的方法调用),除了创建以外我们还需要增加查询讲师、班级、课程的功能(查看相应的信息),管理视图要有6个功能 分析下讲师视图:
讲师视图可查看所授课的班级,班级学生信息 讲师视图具有2个功能 分析下学生视图:
学生视图,要选择学校,选择班级(显示班级的名称,课程,价钱),添加到对应的班级内 咋做数据库呢?!
大致就是这些,最好是能实现一下
二、__enter__ __exit__
其实之前就是接触过关于文件句柄
有两种形式:
f = open( ' a.txt' , 'w+' , encoding = 'utf-8')
with open('a.txt') as f
两个其实是一个效果,但是直接open需要你自己关闭文件,对操作来说不是很方便,如果是with open就方便多了
执行完自动关闭,而其能这么执行依靠的就是__enter__ __exit__两个方法
上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') # return self def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') with Open('a.txt') as f: print('=====>执行代码块') # print(f,f.name) 上下文管理协议
__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行
class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') print(exc_type) print(exc_val) print(exc_tb) with Open('a.txt') as f: print('=====>执行代码块') raise AttributeError('***着火啦,救火啊***') print('0'*100) #------------------------------->不会执行
如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行
class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') print(exc_type) print(exc_val) print(exc_tb) return True with Open('a.txt') as f: print('=====>执行代码块') raise AttributeError('***着火啦,救火啊***') print('0'*100) #------------------------------->会执行
class Open: def __init__(self,filepath,mode='r',encoding='utf-8'): self.filepath=filepath self.mode=mode self.encoding=encoding def __enter__(self): # print('enter') self.f=open(self.filepath,mode=self.mode,encoding=self.encoding) return self.f def __exit__(self, exc_type, exc_val, exc_tb): # print('exit') self.f.close() return True def __getattr__(self, item): return getattr(self.f,item) with Open('a.txt','w') as f: print(f) f.write('aaaaaa') f.wasdf #抛出异常,交给__exit__处理 练习:模拟Open
两大优势:
1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
今晚要早点就寝了,拜拜喽