1
2
3
4
5
6
|
alist
=
[]
with ListTrans(alist) as working:
working.append(
1
)
working.append(
2
)
raise
RuntimeError(
'we are hosed'
)
print
alist
|
生成:
1
|
RuntimeError: we are hosed
|
alist無變化。
能夠捕捉異常:
1
2
3
4
5
6
7
8
9
|
alist
=
[]
try
:
with ListTrans(alist) as working:
working.append(
1
)
working.append(
2
)
raise
RuntimeError(
'we are hosed'
)
except
RuntimeError as e:
print
e
print
alist
|
生成:
1
2
|
we are hosed
[]
|
固然,也能夠簡單的將__exit__的返回值設爲True來忽略異常。
4.contextmanager裝飾器
@contextmanager
contextlib模塊的contextmanager裝飾器能夠更方便的實現上下文管理器。
任何可以被yield關鍵詞分割成兩部分的函數,都可以經過裝飾器裝飾的上下文管理器來實現。任何在yield以前的內容均可以看作在代碼塊執行前的操做,
而任何yield以後的操做均可以放在exit函數中。
1
2
3
4
5
6
7
8
9
10
11
|
from
contextlib
import
contextmanager
@contextmanager
def
listTrans(alist):
thecopy
=
list
(alist)
yield
thecopy
alist[:]
=
thecopy
alist
=
[]
with listTrans(alist) as working:
working.append(
1
)
working.append(
2
)
print
alist
|
yield返回的值至關於__enter__的返回值。
要注意的是,這不是異常安全的寫法,也就是說,當出現異常時,yield後的語句是不會執行的,想要異常安全,可用try捕捉異常:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from
contextlib
import
contextmanager
@contextmanager
def
listTrans(alist):
thecopy
=
list
(alist)
try
:
yield
thecopy
except
RuntimeError:
pass
alist[:]
=
thecopy
alist
=
[]
with listTrans(alist) as working:
working.append(
1
)
working.append(
2
)
raise
RuntimeError
|
nested與closing
contextlib模塊還有兩個好玩的方法:nested,closing。
nested:用來更方便的減小嵌套寫法:
當要嵌套的寫上下文管理器時:
1
2
3
|
with
open
(
'toReadFile'
,
'r'
) as reader:
with
open
(
'toWriteFile'
,
'w'
) as writer:
writer.writer(reader.read())
|
能夠用nested簡化寫法:
1
2
3
|
with contextlib.nested(
open
(
'fileToRead.txt'
,
'r'
),
open
(
'fileToWrite.txt'
,
'w'
)) as (reader, writer):
writer.write(reader.read())
|
python2.7後nested就過期了:
1
2
|
with
open
(
'fileToRead.txt'
,
'r'
) as reader,
open
(
'fileToWrite.txt'
,
'w'
) as writer:
writer.write(reader.read())
|
closing(object):建立上下文管理器,在執行過程離開with語句時自動執行object.close():
1
2
3
4
5
6
7
|
class
Door(
object
) :
def
open
(
self
) :
print
'Door is opened'
def
close(
self
) :
print
'Door is closed'
with contextlib.closing(Door()) as door :
door.
open
()
|