我們看乙個with處理檔案操作的例項:
with open('/etc/passwd') as f:這段**的作用:開啟乙個檔案,如果一切正常,把檔案物件賦值給f,然後用迭代器遍歷檔案中每一行,當完成時,關閉檔案;for line in f:
print(line)
而無論在這段**的任何地方,如果發生異常,此時檔案仍會被關閉。
with看起來如此簡單,但是其背後還有一些工作要做,因為你不能對python的任意物件使用with語句,它僅能工作於支援上下文管理協議(context management protocol)的物件。
也就是說,只有內建了「上下文管理」的物件可以和with一起工作,目前支援該協議的物件有:
當with語句執行時,便執行上下文表示式(context_expr)來獲得乙個上下文管理器,上下文管理器的職責是提供乙個上下文物件,用於在with語句塊中處理細節:
一旦獲得了上下文物件,就會呼叫它的__enter__()方法,將完成with語句塊執行前的所有準備工作,如果with語句後面跟了as語句,則用__enter__()方法的返回值來賦值;
當with語句塊結束時,無論是正常結束,還是由於異常,都會呼叫上下文物件的__exit__()方法,__exit__()方法有3個引數,如果with語句正常結束,三個引數全部都是 none;如果發生異常,三個引數的值分別等於呼叫sys.exc_info()函式返回的三個值:型別(異常類)、值(異常例項)和跟蹤記錄(traceback),相應的跟蹤記錄物件。
因為上下文管理器主要作用於共享資源,__enter__()和__exit__()方法幹的基本是需要分配和釋放資源的低層次工作,
比如:資料庫連線、鎖分配、訊號量加/減、狀態管理、檔案開啟/關閉、異常處理等。
知道了上面這些,我們就可以嘗試在自定義類裡面建立__enter__()和__exit__()方法,來配合with語句建立類例項了:
1
2
3
4
5
6
7
8
9
10
class
a:
def
__enter__(
self
):
print
(
'__enter__() is called'
)
def
__exit__(
self
, e_t, e_v, t_b):
print
(
'__exit__() is called'
)
with a() as a:
print
(
'got instance'
)
輸出:
另外python庫中還有乙個模組contextlib,使你不用構造含有__enter__, __exit__的類就可以使用with:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from
__future__
import
with_statement
from
contextlib
import
contextmanager
@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 context call------'
)
輸出:
老衛帶你學 PYTHON之WITH語句原理
我們看乙個with處理檔案操作的例項 with open etc passwd as f for line in f print line 這段 的作用 開啟乙個檔案,如果一切正常,把檔案物件賦值給f,然後用迭代器遍歷檔案中每一行,當完成時,關閉檔案 而無論在這段 的任何地方,如果發生異常,此時檔案...
Python之if語句,迴圈語句
pythin縮排規則 具有相同縮排的 被視為 塊。s 5 if s 63 print s print t print k 上面第3 4行為乙個 塊,第五行與3 4行不是乙個 塊 若if條件成立,執行3 4句,結束之後執行第5句 否則直接執行第5句。縮排請嚴格按照python的習慣寫法 4個空格 不要...
Python之print語句Python的注釋
print語句可以向螢幕上輸出指定的文字。比如輸出 hello,world 用 實現如下 print hello,world print語句也可以跟上多個字串,用逗號 隔開,就可以連成一串輸出 print the quick brown fox jumps over the lazy dog the...