伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Python_学习之上下文

来源:本站原创 浏览:122次 时间:2022-03-08
  目录

示例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.flagif __name__ == '__main__':   with MyContext(True) as t:       print("执行代码逻辑……")       raise Exception("错误解释")   print("===>当上下文不抛出异常时,此处可以被打印")# t 实际就是类Mycontext的实例化对象,其可以调用类中的任意实例方法和属性

示例3:以装饰器的方式为功能函数加装上下文

import contextlibclass 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 threadingclass 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 = "l����,����ife 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 contextlibdef write_log(data):   if data:       print(111111)   else:       raise Exception("life")with contextlib.suppress(Exception):   data = dict()   write_log(data)# suppress类可以过滤指定的异常,不抛出

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net