原文地址: http://blog.youkuaiyun.com/huithe/article/details/6658831
import sys
class test:
def __enter__(self):
print "enter"
return 1
def __exit__(self,*args):
print "exit"
return True
with test() as t:
print "t is not the result of test().it is __enter__ returned"
print "t is 1,yes,it is {0}".format(t)
#raise NameError("hi here")
#sys.exit()
print "Never here"
在使用锁机制时, 经常会用到with 语句
import threading
_lock = threading.Lock()
with _lock:
...
如果有一個類包含 __enter__ 方法和 __exit__ 方法,像這樣:
class controlled_execution:
def__enter__(self):
set things up
return thing
def__exit__(self, type, value, traceback):
tear things down
那麼它就可以和with一起使用,像這樣:
with controlled_execution() as thing: some code 當with語句被執行的時候,python對表達式進行求值,對求值的結果(叫做“內容守護者”)調用__enter__方法,並把__enter__ 方法的返回值賦給as後面的變量。然後python會執行接下來的代碼段,並且無論這段代碼幹了什麼,都會執行“內容守護者”的__exit__ 方法。
作爲額外的紅利,__exit__方法還能夠在有exception的時候看到exception,並且壓制它或者對它做出必要的反應。要壓制exception,只需要返回一個true。比如,下面的__exit__方法吞掉了任何的TypeError,但是讓所有其他的exceptions通過:
def __exit__(self, type, value, traceback):
return isinstance(value, TypeError)在Python2.5中,file object擁有__enter__和__exit__方法,前者僅僅是返回object自己,而後者則關閉這個文件:
>>> f = open("x.txt")
>>> f
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.__enter__()
<open file 'x.txt', mode 'r' at 0x00AE82F0>
>>> f.read(1)
'X'
>>> f.__exit__(None, None, None)
>>> f.read(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
這樣要打開一個文件,處理它的內容,並且保證關閉它,你就可以簡簡單單地這樣做:
with open("x.txt") as f:
data = f.read()
do something with data我的補充:
數據庫的連接好像也可以和with一起使用,我在一本書上看到以下內容:
conn = sqlite.connect("somedb")
with conn:
conn.execute("insert into sometable values (?,?)",("foo","bar"))
在這個例子中,commit()是在所有with數據塊中的語句執行完畢並且沒有錯誤之後自動執行的,如果出現任何的異常,將執行rollback()
操作,再次提示異常。