1.with語句時用於對try except finally 的優化,讓代碼更加美觀,
例如常用的開發文件的操作,用try except finally 實現:
f=open('file_name','r') try: r=f.read() except: pass finally: f.close()
打開文件的時候,為了能正常釋放文件的句柄,都要加個try,然后再finally里把f close掉,但是這樣的代碼不美觀,finally就像個尾巴,一直托在后面,尤其是當try里面的語句時幾十行
用with的實現:
with open('file_name','r') as f: r=f.read()
這條語句就好簡潔很多,當with里面的語句產生異常的話,也會正常關閉文件
2.除了打開文件,with語句還可以用於哪些地方呢?
with只適用於上下文管理器的調用,除了文件外,with還支持 threading、decimal等模塊,當然我們也可以自己定義可以給with調用的上下文管理器
2.1使用類定義上下文管理器
class A(): def __enter__(self): self.a=1 return self def f(self): print 'f' def __exit__(self,a,b,c): print 'exit' def func(): return A() with A() as a: 1/0 a.f() print a.a
使用類定義上下文管理器需要在類上定義__enter__和__exit__方法,執行with A() as a: 語句時會先執行__enter__方法,這個方法的返回值會賦值給后面的a變量,當with里面的語句產生異常或正常執行完時,都好調用類中的__exit__方法。
2.2使用生成器定義上下文管理器
from contextlib import contextmanager @contextmanager def demo(): print '這里的代碼相當於__enter__里面的代碼' yield 'i ma value' print '這里的代碼相當於__exit__里面的代碼' with demo() as value: print value
2.3 自定義支持 closing 的對象
class closing(object): def __init__(self, thing): self.thing = thing def __enter__(self): return self.thing def __exit__(self, *exc_info): self.thing.close() class A(): def __init__(self): self.thing=open('file_name','w') def f(self): print '運行函數' def close(self): self.thing.close() with closing(A()) as a: a.f()
在開發的過程中,會有很多對象在使用之后,是需要執行一條或多條語句來進行關閉,釋放等操作的,例如上面說的的文件,還有數據庫連接,鎖的獲取等,這些收尾的操作會讓代碼顯得累贅,也會造成由於程序異常跳出后,沒有執行到這些收尾操作,而導致一些系統的異常,還有就是很多程序員會忘記寫上這些操作-_-!-_-!,為了避免這些錯誤的產生,with語句就被生產出來了。with語句的作用就是讓程序員不用寫這些收尾的代碼,並且即使程序異常也會執行到這些代碼(finally的作用)