python学习笔记整理tcy1: with上下文管理
上下文管理器類型?2018/7/8
https://docs.python.org/3.7/library/
參考書:Python參考手冊+第4版_修訂版
--------------------------------------------------------------------------
1.自定義上下文管理器
定義:
class list_withFun(object):
??? def__init__(self,lst):
???????self.lst=lst
??? def__enter__(self):
??????self.old_data=list(self.lst)
??????return self.old_data
??? def__exit__(self,type,value,trackback):
???????if type is None:
???????????self.lst[:]=self.old_data
???????return True
調用1:
items=[1,2,3]
with list_withFun(items) as s:
???s.append(4)
???s.append(5)
???print(items)
調用2
try:
???with list_withFun(items) as s:
???????s.append(6)
???????s.append(7)
???????raise RuntimeError('we are hosed')
???????print('error')
except RuntimeError:
?? pass
print(items)
##
***********************************************************
定義:
from contextlib import contextmanager
?
@contextmanager
def list_withFun1(lst):
???old_data=list(lst)? ?#yield 語句前:初始化資源
???yield old_data ??????#返回值
???lst[:]=old_data????? #yield 語句后:釋放資源,處理異常
調用
items=[11,12,13]
with list_withFun(items) as s:
???s.append(14)
???s.append(15)
???print(items)
------------------------------------------------------------------------------
2.應用
with 語句適用對資源訪問場合(上下文管理器對象),確保不管使用過程中是否發生
異常都執行清理,釋放資源,如文件用后自動關閉、線程中鎖自動獲取和釋放等。
對象有:
file;decimal.Context;thread.LockType;threading.Lock;threading.Rlock;
threading.Condition;threading.Semaphore;threading.BoundedSemaphore
------------------------------------------------------------------------------
3.1.語法格式:
contextmanager.__enter__()
輸入運行時此方法返回的值綁定到使用此上下文管理器as的with語句子句中的標識符。
?
contextmanager.__exit__(exc_type,exc_val,exc_tb?)
退出運行返回bool,是否抑制發生異常。True異常忽略;False重新拋出異常
執行with語句正文發生異常,參數包含異常類型,值和追溯信息或3個None。
withcontext_expression [as target(s)]:
??? with-body
參數:
context_expression 要返回一個上下文管理器對象;
__enter__() 方法的返回值賦值給 target(s)。target(s) 是單變量,或者由“()”括起來的元組
------------------------------------------------------------------------------
3.2.example
文件操作:
with open(r'somefileName') as somefile:
??? for line in somefile:
?? ?????print line
??????? # ...more code
?
try/finally 操作文件
somefile = open(r'somefileName')
try:
??? for line in somefile:
??????? print line
??????? # ...more code
finally:
??? somefile.close()
-------------------------------------------------------------------------------
定義:
class A(object):
??? def __enter__(self):
??????? print('__enter__()called')
??????? return self
???
??? def print_hello(self):
??????? print("helloworld!")
?
??? def __exit__(self, e_t,e_v, t_b):
??????? print('__exit__()called')
調用:
with A() as a:??? # a為__enter__的返回對象
??? a.print_hello()
??? print('got instance')
輸出:
__enter__() called
hello world!
got instance
__exit__() called
-------------------------------------------------------------------------------
4.自定義上下文管理器contextlib模塊
4.1.裝飾器 contextmanager
生成器函數被裝飾以后,返回的是一個上下文管理器
裝飾器contextmanager 使用示例
from contextlib import contextmanager
@contextmanager
def demo():
??? print '[Allocateresources]'? # yield 之前的語句在 __enter__() 方法中執行;資源分配
??? print 'Code beforeyield-statement executes in __enter__'
??? yield '*** contextmanagerdemo ***'#返回值
??? print 'Code afteryield-statement executes in __exit__'
??? print '[Free resources]'? ??# yield 之后的語句在 __exit__() 中執行;資源釋放
調用:
with demo() as value:
??? print 'Assigned Value: %s'% value
輸出:
[Allocate resources]
Code beforeyield-statement executes in __enter__
Assigned Value: ***contextmanager demo ***
Code afteryield-statement executes in __exit__
[Free resources]
??????
定義:
@contextmanager
def context():
??? print('entering the zone')
??? try:
??????? yield
??? except Exception as e:
??????? print('with an error%s'%e)
??????? raise e
??? else:
????? print('with no error')
調用:
with context():
??? print('----in contextcall------')
?
輸出:
entering the zone
----in contextcall------
with no error
-------------------------------------------------------------------------------
?
4.2.函數 nested可以將多個上下文管理器組織在一起,避免使用嵌套 with 語句。
with nested(A(), B(), C()) as (X, Y, Z):
???? # with-body code here
類似于:
with A() as X:
??? with B() as Y:
??????? with C() as Z:
???????????? # with-body codehere
需要注意:
發生異常后,如果某個上下文管理器的 __exit__() 方法對異常處理返回 False,
則更外層的上下文管理器不會監測到異常。
-------------------------------------------------------------------------------
?
4.3.上下文管理器closing
適用提供close() 實現的對象如網絡連接、數據庫連接等,
可以在自定義類時通過接口 close() 來執行所需要的資源“清理”工作。
class closing(object):
??? # help doc here
??? def __init__(self,thing):
??????? self.thing = thing
??? def __enter__(self):
??????? return self.thing
??? def __exit__(self,*exc_info):
??????? self.thing.close()
?
自定義支持 closing 的對象
class ClosingDemo(object):
??? def __init__(self):
??????? self.acquire()
??? def acquire(self):
??????? print 'Acquireresources.'
??? def free(self):
??????? print 'Clean up anyresources acquired.'
??? def close(self):
??????? self.free()
調用:
with closing(ClosingDemo()):
??? print 'Using resources'
輸出:
Acquire resources.
Using resources
Clean up anyresources acquired.
-------------------------------------------------------------------------------
?
總結
以上是生活随笔為你收集整理的python学习笔记整理tcy1: with上下文管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机房租赁,租赁机房与自建机房对比
- 下一篇: ssm欢欢宠物医院管理系统的设计与实现