with
語句適用於對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如文件使用後自動關閉/線程中鎖的自動獲取和釋放等。
緊跟with
後面的語句被求值後,返回對象的__enter__()
方法被調用,這個方法的返回值將被賦值給as
後面的變量。
當with後面的代碼塊全部被執行完之後,將調用前面返回對象的__exit__()
方法。
例如:
class SqlHelper(object):
def __enter__(self):
return 123
def __exit__(self, exc_type, exc_val, exc_tb):
print("in __exit__")
# 創建Sqlhelper對象
sqlhelper = SqlHelper()
with sqlhelper as f:
print(f)
運行上面代碼輸出:
123
in __exit__
說明with
會首先執行 SqlHelper
類裡面的__enter__()
方法,並將__enter__()
方法的返回值賦值給f
,因此打印出f
就是__enter__()
的返回值。
當執行完後,會執行__exit__()
方法。
__exit__()
方法中有3個參數, exc_type
, exc_val
, exc_tb
,這些參數在異常處理中相當有用。
例如:
class Sample():
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print "type: ", exc_type
print "val: ", exc_val
print "tb: ", exc_tb
def do_something(self):
bar = 1 / 0
return bar + 10
with Sample() as sample:
sample.do_something()
運行程序輸出:
in enter
Traceback (most recent call last):
type: <type 'exceptions.ZeroDivisionError'>
val: integer division or modulo by zero
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 36, in <module>
tb: <traceback object at 0x7f9e13fc6050>
sample.do_something()
File "/home/user/cltdevelop/Code/TF_Practice_2017_06_06/with_test.py", line 32, in do_something
bar = 1 / 0
ZeroDivisionError: integer division or modulo by zero
Process finished with exit code 1