with语法
with语句实质上是上下文管理,是try...finally...的简化
1 try: 2 f = open('/path/to/file', 'r') 3 f.read() 4 finally: 5 if f: 6 f.close() 7 8 -------------------------------------- 9 10 with open('/path/to/file', 'r') as f: 11 f.read()
任何对象,只要正确使用了上下文管理器,就可以使使用with
实现上下文管理只要定义__enter__和__exit__即可
1 class Query(object): 2 def __init__(self, name): 3 self.name = name 4 5 def __enter__(self): 6 print('I entered') 7 return self 8 9 def __exit__(self, exc_type, exc_value, traceback): 10 if exc_type: 11 print('Error') 12 else: 13 print('End') 14 15 def query(self): 16 print('Query info about %s...' % self.name)
在调用构造之前调用__enter__
,在执行完with里面的代码块之后调用__exit__
使用:with 构造对象 as 对象变量名
1 with Query('Martin') as q: 2 q.query()
编写__enter__
和__exit__
仍然很繁琐,因此Python的标准库contextlib提供了更简单的写法,上面的代码可以改写如下:
1 from contextlib import contextmanager 2 3 class Query(object): 4 def __init__(self, name): 5 self.name = name 6 7 def query(self): 8 print('Query info about %s...' % self.name) 9 10 11 @contextmanager 12 def create_query(name): 13 print('Begin') 14 q = Query(name) 15 yield q 16 print('End')
使用:with 其他函数 as 对象变量名:
1 with create_query('Bob') as q: 2 q.query()
执行顺序:
-
打印”Begin“,初始化一个q对象
-
q对象返回到with,即 as q
-
执行q.query()
-
打印"End"