Python_学习之上下文
2021-04-03 23:48
1131 查看
目录
示例1:查看上下文执行的顺序
示例2:动态控制上下文是否抛出异常
示例3:以装饰器的方式为功能函数加装上下文
示例4:过滤异常,不抛出
在之前我们进行过文件操作的学习时,我们为了不忘掉文件操作完毕后关闭文件file.close(),官方推荐推荐我们使用with……as 语句,这其实本质就是运用了python的上下文管理。
而所谓的上下文,其实就是服务运行的状态从进入到退出的一种过程,python中我们常常通过上下文来进行资源的创建与释放。
语法:with……as
本质:
程序执行with中的代码时,会自动先执行enter方法,返回在这个上下文中使用的对象句柄,程序执行完逻辑后自动调用exit来进行资源的释放
示例1:查看上下文执行的顺序
如果上下文中出现异常即执行逻辑代码过程中,上下文是可以捕获异常的,并且默认是抛出异常的
class MyContext: def __init__(self): print("in __init__") def __enter__(self): print("int __enter__") return self def __exit__(self, exc_type, exc_val, exc_tb): """""" print("in __exit__") print("异常的类型exc_type=", exc_type) print("异常抛出的值exc_type=", exc_val) print("异常的traceback对象exc_type=", exc_tb) if __name__ == '__main__': with MyContext() as t: print("执行代码逻辑……") raise Exception("错误解释") # 执行结果为 """ in __init__ int __enter__ 执行代码逻辑…… in __exit__ 异常的类型exc_type= <class 'Exception'> 异常抛出的值exc_type= 错误解释 异常的traceback对象exc_type= <traceback object at 0x000001B52B5465C8> Traceback (most recent call last): File "D:/my_all_project/Frame_learning/test.py", line 27, in <module> raise Exception("错误解释") Exception: 错误解释 """
示例2:动态控制上下文是否抛出异常
如果功能函数逻辑中出现异常,而exit方法返回值等价于False就会抛出异常,否则不抛出异常,继续执行上下文外面的业务逻辑
class MyContext: def __init__(self, flag): print("in __init__") self.flag = flag def __enter__(self): print("int __enter__") "可以返回我们定义任何方法或实例化的对象" return self def __exit__(self, exc_type, exc_val, exc_tb): """""" print("in __exit__") print("异常的类型exc_type=", exc_type) print("异常抛出的值exc_type=", exc_val) print("异常的traceback对象exc_type=", exc_tb) return self.flag if __name__ == '__main__': with MyContext(True) as t: print("执行代码逻辑……") raise Exception("错误解释") print("===>当上下文不抛出异常时,此处可以被打印") # t 实际就是类Mycontext的实例化对象,其可以调用类中的任意实例方法和属性
示例3:以装饰器的方式为功能函数加装上下文
import contextlib class MyContext(contextlib.ContextDecorator): def __init__(self): print(f'__init__()') def __enter__(self): print(f'__enter__()') return self def __exit__(self, exc_type, exc_val, exc_tb): print(f'__exit__()') print(f"exc_type:{exc_type}") try: self.write_log() except Exception as e: print(e) @staticmethod def write_log(): print("开始记录日志") log = dict(req_body="request", rsp_body="response") f = open("my_log_test.txt", "w", encoding="utf-8") import json f.write(json.dumps(log, ensure_ascii=False)) f.flush() f.close() raise Exception("本日志记录报错,不在影响功能函数的正常返回") @MyContext() def func(flag): code, desc = 1, "fail" try: if flag: raise Exception("测试上下文是否能捕获异常") else: code, desc = 0, "success" except Exception as e: print(f"本初捕获异常:{e},则不会再抛给上下文管理器中") else: code, desc = 0, "success" finally: return {"code": code, "desc": desc} if __name__ == '__main__': ret = func(True) print(ret) # 本小例是通过上下文初试为功能函数添加记录日志的功能,不因记录日志出现异常导致功能函数异常,也可以加一个开关,是否记录日志 # 写日志的另一个版本 import threading class WriteLogContext: def __init__(self, flag, data): """ :param flag: 异常日志是否抛出开关标识 :param data: 日志内容 """ self.flag = flag self.data = data def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): print("异常的类型exc_type=", exc_type) print("异常抛出的值exc_type=", exc_val) print("异常的traceback对象exc_type=", exc_tb) return self.flag def write_action(self): """开启多线程记录日志,发现异常不会抛出外层,但会将异常打印到控制台""" write_external_thread = threading.Thread(target=self.write_log, args=(self.data,)) write_external_thread.setDaemon(True) write_external_thread.start() @staticmethod def write_log(log): with open("test.txt", "a") as file: file.write("入库的操作模拟\n") file.write(f"{log}\n") file.flush() # 模拟异常 raise TypeError("模拟写日志过程中的异常,发现本处报错,并不会影响主功能函数响应") def access(): # 执行业务 print("business is begin") # 记录流水 log = "life is short ,i use python ,i use it for make money" with WriteLogContext(flag=True, data=log) as f: f.write_action() # 响应 result = "business is success" return result
示例4:过滤异常,不抛出
import contextlib def write_log(data): if data: print(111111) else: raise Exception("life") with contextlib.suppress(Exception): data = dict() write_log(data) # suppress类可以过滤指定的异常,不抛出
相关文章推荐
- 三十一、python学习之Flask框架(三)视图:路由、上下文、Flask-Script扩展
- Python深入学习之上下文管理器
- Python基础学习(5)网络编程socket、文件上传、粘包问题、socketserver、IO多路复用、线程与进程、进程池、线程池、上下文管理、协程
- Python中的with语句与上下文管理器学习总结
- python 学习第十一课 上下文管理 paramiko 堡垒机 mysql操作
- python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)
- Python 学习笔记 - 上下文
- Python深入学习之上下文管理器
- Python上下文管理器学习
- python学习笔记:利用contextlib和@contextmanager实现with语句上下文实例
- python.pygal/reuqests学习范例-爬取github上Python热度并数据化显示
- 初始学习python
- Python学习Day16从Web网络解析到网络空间、玫瑰花绘制案例
- Python学习笔记:1.3.5 异常处理
- python学习-字符串的基本操作
- Python学习第〇篇-主要概念及示例
- python学习之路
- numpy学习笔记1---python学习笔记32
- 零基础学习python_类和对象(36-40课)
- Python学习笔记--使用Zbar解码二维码