Loading... 1.实现了上下文协议的对象可以使用with关键字 2.实现了上下文协议的对象通常称为上下文管理器 3.只要对象实现了__enter__和__exit__就是实现了上下文协议 4.上下文表达式必须要返回一个上下文管理器(with xxx():就是上下文表达式) class MyResource: def __enter__(self): print("connect to resource") return self def __exit__(self, exc_type, exc_val, exc_tb): """ :param exc_type: 错误类型 :param exc_val: 错误信息 :param exc_tb: traceback对象 :return: """ if exc_tb: # 可以在这里处理异常 print("process exception") else: print("no exception") print("close resource connection") # __exit__方法必须要返回一个True或者False,如果什么都不返回,就会返回False # 当with中发生了异常,若返回True则在with语句外部则不会在抛出异常;若是False则会再次抛出异常 return True def query(self): print("query data") with MyResource() as resource: # as 后面的变量是__enter__中返回的值 resource.query() # 执行顺序 __enter__ -> query -> __exit__ 使用contextmanager来简化MyResource定义 from contextlib import contextmanager # contextmanager好处是将不是上下管理器的类变成了一个管理器 class MyResource: def query(self): print("query data") @contextmanager def make_my_resource(): # __enter__ print("connect to resource") yield MyResource() # __exit__ print("close resource connection") with make_my_resource() as resource: resource.query() eg1:实现给一个字符串前后加上书名号 from contextlib import contextmanager @contextmanager def book_mark(): print("《", end="") yield print("》", end="") with book_mark(): print("唐诗三百首", end="") # output: 《唐诗三百首》 eg2:给SQLAlchemy添加一个auto_commit from contextlib import contextmanager from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy class SQLAlchemy(_SQLAlchemy): @contextmanager def auto_commit(self): try: yield self.session.commit() except Exception as e: db.session.rollback() raise e db = SQLAlchemy() with db.auto_commit(): user = User() user.name = "xiaoming" user.password = "hello" db.session.add(user) Last modification:April 12th, 2019 at 12:04 am © 允许规范转载 Support If you think my article is useful to you, please feel free to appreciate ×Close Appreciate the author Sweeping payments