魔術方法
上下文管理
檔案io操作可以對檔案物件使用上下文管理,使用with……as語法
with open('test') as f:
pass
仿照上例寫乙個自己的類
提示錯誤
上下文管理物件
方法意義
enter進入與此物件相關的上下文,如果存在該方法,with語法會把該方法的返回值作為繫結到as子句中指定的變數上
exit退出與此物件相關的上下文
例項化物件的時候,並不會呼叫enter,進入with語句塊呼叫__enter__方法,然後執行語句體,最後離開with語句塊的時候,呼叫__exit__方法。
with可以開啟乙個上下文執行的環境,在執行前做一些準備工作,執行後做一些收尾工作。
注意,with並不開啟乙個新的作用域。
上下文管理的安全性
可以看出在enter和exit照樣執行,上下文管理是安全的。
with語句
class point:
def __init__(self):
print('init')
def __enter__(self):
print('enter')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
f=open('c:/users/asus/pycharmprojects/untitled1/venv/質數.py')
問題在於__enter__方法上,它將自己的返回值賦給f
方法的引數
__enter__方法沒有其他引數
__exit__方法有3個引數
exit(self, exc_type, exc_val, exc_tb)三個引數與異常有關。
如果該上下文退出時沒有異常,這3個引數都為none.
如果有異常,引數意義如下:
exc_type,異常型別
exc_value,異常的值
traceback,異常的追蹤資訊
__exit__方法返回乙個等效true的值,則壓制異常,否則,繼續丟擲異常
上下文應用場景
1、增強功能:在**執行的前後增強**,以增強其功能。類似裝飾器的功能
2、資源管理:開啟了資源需要關閉
3、許可權驗證:在執行**之前,做許可權的驗證,在__enter__中處理
contextlib.contextmanager
contextlib.contextmanager它是乙個裝飾器實現上下文管理,裝飾乙個函式,而不用像類一樣實現__enter__和__exit__方法。對下面的函式有要求:必須有yield,也就是這個函式必須返回乙個生成器,且只要yield乙個值。
也就是說這個裝飾器接受乙個生成器物件作為引數
f接收yield語句的返回值。
上面的程式看似不錯但是,增加乙個異常發現並不能保證exit的執行,增加try finally
import contextlib
@contextlib.contextmanager
def foo():
try:
print('enter')
yield 1
finally:
print('exit')
return 1
with foo() as f:
raise exception()
print(f)
當yield發生處為生成器函式增加了上下文管理,這是為函式增加上下文機制的方式
總結:如果業務邏輯簡單可以使用函式如contextlib.contextmanager裝飾器方式,如果業務複雜,用類的方式如__enter__和__exit__方法方便
魔術方法之上下文管理
檔案io操作可以對檔案物件使用上下文管理,使用with as語法。with open test as f pass仿照上例寫乙個自己的類,實現上下文管理 classa pass with a as f attributeerror enter pass提示屬性錯誤,沒有 enter 看來需要這個類屬...
python的魔術方法之上下文管理
方法意義 enter 進入與此物件相關的上下文。如果存在該方法,with語法會把該方法的返回值作為繫結到as子句中指定的變數上 exit 退出與此物件相關的上下文。import time class point def init self print 1 init time.sleep 1 prin...
魔術方法 上下文管理
檔案io操作可以對檔案物件使用上下文管理,使用with as語法 上下文管理物件 方法意義 enter 進入與此物件相關的上下文.如果存在該方法,with語法會把該方法的返回值作為繫結到as子句中指定的變數上 exit 退出與此物件相關的上下文 例項化物件的時候,並不會呼叫enter,進入with語...