Python魔術方法之上下文管理

2021-09-23 15:39:53 字數 3609 閱讀 7857

魔術方法

上下文管理

檔案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語...