上下文管理器對象存在的目的就是管理with語句。上下文管理器協(xié)議包含__enter__ 和__exit__ 兩個方法。with 語句開始運行時,會在上下文管理器對象上調(diào)用__enter__ 方法。with 語句運行結(jié)束后,會在上下文管理器對象上調(diào)用__exit__ 方法
來看一個例子,把文件對象當成上下文管理器使用
with
open
(
'test.dat'
)
as
fp
:
secc
=
fp
.
read
(
20
)
>>
>
len
(
src
)
20
>>
>
fp
<
_io
.
TextIOWrapper name
=
'mirror.py'
mode
=
'r'
encoding
=
'UTF-8'
>
>>
>
fp
.
closed
,
fp
.
encoding
(
True
,
'UTF-8'
)
"""
但是不能在fp 上執(zhí)行I/O 操作,因為在with 塊的末尾,調(diào)用TextIOWrapper.__exit__
方法把文件關(guān)閉了。
"""
>>
>
fp
.
read
(
60
)
Traceback
(
most recent call last
)
:
File
"
"
,
line
1
,
in
<
module
>
ValueError
:
I
/
O operation on closed
file
.
執(zhí)行with后面的表達式得到的結(jié)果是上下文管理器對象,不過,把值綁定到目標變量上(as子句)是上下文管理器調(diào)用__enter__方法的結(jié)果
來看一個例子,自己實現(xiàn)一個上下文管理器
class
Sample
(
)
:
def
__enter__
(
self
)
:
print
(
"in __enter__"
)
return
self
def
__exit__
(
self
,
exc_type
,
exc_val
,
exc_tb
)
:
print
(
"in __exit__"
)
def
do_something
(
self
)
:
print
(
"i am doing something"
)
>>
>
with
Sample
(
)
as
sample
:
sample
.
do_something
(
)
in
__enter__
i am doing something
in
__exit__
真?zhèn)€過程運行如下,enter()方法被執(zhí)行,enter()方法返回值,在這里是類自身,執(zhí)行代碼塊sample.do_something(), 最后是exit()方法被調(diào)用
contextlib模塊中的使用工具
@contextmanager 裝飾器能減少創(chuàng)建上下文管理器的樣板代碼量,因為不用編寫一個完整的類,定義__enter__ 和__exit__方法,而只需實現(xiàn)有一個yield 語句的生成器,生成想讓__enter__ 方法返回的值。
在使用@contextmanager 裝飾的生成器中,yield語句的作用是把函數(shù)的定義體分成兩部分**:yield 語句前面的所有代碼在with 塊開始時(即解釋器調(diào)用__enter__方法時)執(zhí)行,yield 語句后面的代碼在with 塊結(jié)束時(即調(diào)用__exit__ 方法時)執(zhí)行**
看一個使用contextmanager實現(xiàn)上下文管理器的例子
import
contextlib
@contextlib
.
contextmanager
def
Sample
(
)
:
def
do_something
(
)
:
print
(
'i am doing something'
)
print
(
"in __enter__"
)
yield
do_something
print
(
"in exit"
)
>>
>
with
Sample
(
)
as
sample
:
sample
(
)
in
__enter__
i am doing something
in
__exit__
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
