1. 背景關系管理器
一個類只要實作了 __enter__() 和 __exit__() 這個兩個方法,通過該類創建的物件我們就稱之為背景關系管理器,
背景關系管理器可以使用 with 陳述句,with陳述句之所以這么強大,背后是由背景關系管理器做支撐的,也就是說剛才使用 open 函式創建的檔案物件就是就是一個背景關系管理器物件,
自定義背景關系管理器類,模擬檔案操作:
定義一個File類,實作 __enter__() 和 __exit__() 方法,然后使用 with 陳述句來完成操作檔案, 示例代碼:
# 自定義背景關系管理器類
class File(object):
def __init__(self, file_name, file_mode):
self.file_name = file_name
self.file_mode = file_mode
def __enter__(self):
# 上文方法,負責回傳操作物件資源,比如:檔案物件,資料庫連接物件
self.file = open(self.file_name, self.file_mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
# 下文方法,負責釋放物件資源,比如:關閉檔案,關閉資料庫連接物件
self.file.close()
print('over')
# with陳述句 結合背景關系管理器物件使用
with File('1.txt', 'r') as f:
# content = f.read()
# print(content)
f.write('qqq') # 報錯,但是仍然執行了關閉連接操作
代碼說明:
__enter__表示上文方法,需要回傳一個操作檔案物件__exit__表示下文方法,with陳述句執行完成會自動執行,即使出現例外也會執行該方法
2. 背景關系管理器裝飾器方式實作
假如想要讓一個函式成為背景關系管理器,Python 還提供了一個 @contextmanager 的裝飾器,更進一步簡化了背景關系管理器的實作方式,通過 yield 將函式分割成兩部分,yield 上面的陳述句在 __enter__ 方法中執行,yield 下面的陳述句在 __exit__ 方法中執行,緊跟在 yield 后面的引數是函式的回傳值,
from contextlib import contextmanager
# 加上裝飾器,那么下面函式創建的物件就是一個背景關系管理器
@contextmanager
def my_open(file_name, file_mode):
global file
try:
file = open(file_name, file_mode)
# yield關鍵字之前的代碼可以認為是上文方法,負責回傳操作物件資源
yield file
except Exception as e:
print(e)
finally:
# yield關鍵字后面的代碼可以認為是下文方法,負責釋放操作物件的資源
file.close()
print('over')
# 普通函式不能結合with陳述句使用
with my_open('1.txt', 'r') as file:
# content = file.read()
# print(content)
file.write('1')
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/139219.html
標籤:其他
