python with關鍵字做了些啥?

2021-10-07 20:00:39 字數 2545 閱讀 9467

python 上下文管理協議

我們時常會使用如下的**

with open('1.txt') as f:

print(f.readlines())

我們被告知這樣可以「安全」的開啟乙個檔案。因為當**執行超出 with 的作用域時檔案會自動關閉。

那這是怎麼做到的呢。這就涉及到python上下文管理協議。

乙個物件的實現使用了一對專門方法。

__enter__:該方法在進入上下文時被呼叫,要求返回乙個物件,被 as 關鍵字後的變數所引用。

__exit__:該方法在退出上下文時被呼叫, 一般用於清理當前上下文環境。

如上面的**中。我們知道 open 函式會返回乙個檔案物件。而這個物件就實現了___enter____exit__方法,而後者中就包含自動將檔案物件關閉的**。

因為這樣寫能安全的開啟和關閉檔案。而不再需要自己手動關閉,這樣防止自己忘記關閉檔案物件。

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']

可以看到 open 函式返回的檔案物件實現了__enter____exit__方法。

接來下我們自己實現乙個滿足上下文管理協議的物件吧。

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

這段**中,在 with 上下文中,能修改了標準輸出,因此中間的print語句都不會列印到螢幕中。當脫離上下文時自動恢復。

好像有點意思,但是,這還遠遠不夠哦。因為要實現乙個上下文協議,貌似還挺麻煩的。

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.代表當前類的物件...