python 上下文管理協議
我們時常會使用如下的**
我們被告知這樣可以「安全」的開啟乙個檔案。因為當**執行超出 with 的作用域時檔案會自動關閉。with open('1.txt') as f:
print(f.readlines())
那這是怎麼做到的呢。這就涉及到python
上下文管理協議。
乙個物件的實現使用了一對專門方法。
__enter__
:該方法在進入上下文時被呼叫,要求返回乙個物件,被 as 關鍵字後的變數所引用。
__exit__
:該方法在退出上下文時被呼叫, 一般用於清理當前上下文環境。
如上面的**中。我們知道 open 函式會返回乙個檔案物件。而這個物件就實現了___enter__
,__exit__
方法,而後者中就包含自動將檔案物件關閉的**。
因為這樣寫能安全的開啟和關閉檔案。而不再需要自己手動關閉,這樣防止自己忘記關閉檔案物件。
可以看到 open 函式返回的檔案物件實現了print(dir(open('1.txt')))
# 輸出結果
['_chunk_size', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkclosed', '_checkreadable', '_checkseekable', '_checkwritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']
__enter__
和__exit__
方法。
接來下我們自己實現乙個滿足上下文管理協議的物件吧。
這段**中,在 with 上下文中,能修改了標準輸出,因此中間的print語句都不會列印到螢幕中。當脫離上下文時自動恢復。import sys
class a:
def __init__(self, stdout=none):
from io import stringio
self.stdout = stdout or stringio()
self.old = sys.stdout
def __enter__(self):
sys.stdout = self.stdout
return self.stdout
def __exit__(self,xc_type, exc_val, exc_tb):
sys.stdout = self.old
with a() as stdout:
print('inner')
print('outter')
#輸出結果
outter
好像有點意思,但是,這還遠遠不夠哦。因為要實現乙個上下文協議,貌似還挺麻煩的。
python 提供了乙個裝飾器用於快速實現。
這段**的作用和上一段等效import contextlib
@contextlib.contextmanager
def a(stdout=none):
old = sys.stdout
if stdout is none:
from io import stringio
stdout = stringio()
sys.stdout = stdout
yield stdout
sys.stdout = old
with a() as stdout:
print('inner')
print('outter')
yield 之前的**相當於`__enter__`函式, yield 之後的**相當於 `__exit__`函式。
學會了嗎?
python with關鍵字學習
1.with語句時用於對try except finally 的優化,讓 更加美觀,例如常用的開發檔案的操作,用try except finally 實現 f open file name r try r f.read except pass finally f.close 開啟檔案的時候,為了能正...
python with關鍵字 I O好伴侶
學習python的朋友都知道檔案讀寫的基本操作,通常我們讀寫文字的姿勢是這個樣子的 f open file name f.close 每次定義乙個檔案讀寫物件,在操作完成後,我們都需要進行關閉操作,如果你一不小心忘記了,恭喜你中獎了?你的程式很可能發生記憶體洩露,然後記憶體溢位,然後就掛了。這樣的事...
new關鍵字 this關鍵字 base關鍵字
使用new,所做的三件事 1.類是引用物件,引用物件是在堆中開闢空間 在堆中開闢空間 2.在開闢的堆空間中建立物件 3.呼叫物件的構建函式 4.隱藏父類成員 子類的成員可以與隱藏從父類繼承的成員,類似於重寫。public new void sayhello this關鍵字的使用 1.代表當前類的物件...