with open() as 的用法 和 with上下文管理器(Context manager)
with open() as 的用法 和 with上下文管理器(Context manager)
一、基礎讀寫:
讀⽂件:
1、以讀的⽅式開啟⽂件
f = open(“1.txt”, “r”)
2、讀取⽂件內容
str = f.read()
print(str)
3、關閉⽂件
f.close()
寫⽂件:
1、以寫的⽅式開啟⽂件
f = open(“2.txt”, “w”)
2、寫⼊⽂件內容
str = f.write(“Welcome to 北京!”)
3、關閉⽂件
f.close()
二、 錯誤程式碼示範:
這種⽅式存在的問題是什麼?
1、以讀的⽅式開啟⽂件
f = open(“1.txt”, “r”)
2、讀取⽂件內容
f.write(“xxxxx”)
f.close()
由於⽂件讀寫時都有可能產⽣ IOError ,⼀旦出錯,後⾯的 f.close() 就不會調⽤。
三、優化程式碼:
1)為了保 證⽆論是否出錯都能正確地關閉⽂件,我們可以使⽤ try … finally 來實現:
try:
1、以讀的⽅式開啟⽂件
f = open(“1.txt”, “r”)
2、讀取⽂件內容
f.write(“xxxxx”)
except IOError as e:
print(“⽂件操作出錯”, e)
finally:
f.close()
2)Python引⼊了 with 語句來⾃動幫我們調⽤ close() ⽅法:
try:
1、以讀的⽅式開啟⽂件
with open(“1.txt”, “r”) as f:
2、讀取⽂件內容
f.write(“xxxxx”)
except IOError as e:
print(“⽂件操作出錯”, e)
》這和前⾯的 try … finally 是⼀樣的,但是程式碼更佳簡潔,並且不必調⽤ f.close() ⽅法。
》使⽤ with 關鍵字。open ⽅法的返回值賦值給變數 f,當離開 with 程式碼塊 的時候,系統能夠⾃動調⽤ f.close() ⽅法
四、 with 的原理之上下文管理器
with 的原理前要涉及到另 外⼀個概念,就是上下⽂管理器(Context Manager)。
1)上下文理解成(語言)環境就可以,(⽽且上下⽂雖然叫上下⽂,但是程式⾥⾯⼀ 般都只有上⽂⽽已,只是叫的好聽叫上下⽂。。
2)上下⽂管理器本質就是能夠⽀持with操作。 任何實現了__enter__() 和 __exit__()
⽅法的物件都可稱之為上下⽂管理器,上下⽂管理器物件可以使 ⽤ with 關鍵字。顯然,⽂件(file)物件也實現了上下⽂管理器協議。
一、程式碼演示:
""" 類: MyFile() 類方法: 1. __enter__() 上文方法 2. __exit__() 下文方法 3. __init__() 方法,接收引數並且初始化 目的:驗證上下⽂管理器(Context Manager) with MyFile('hello.txt', 'r') as file: file.read() """ class MyFile(object): # 1. __enter__() 上文方法 def __enter__(self): print("進入上文....") # 1,開啟檔案 self.file = open(self.file_name, self.file_model) # 2,返回開啟的檔案資源 return self.file # 2. __exit__() 下文方法 def __exit__(self, exc_type, exc_val, exc_tb): print("進入下文....") # 關閉檔案資源 self.file.close() # 3. __init__() 方法,接收引數並且初始化 def __init__(self, file_name, file_model): # 區域性變數定義成例項屬性 -> 在類裡面呼叫 # 儲存檔名和檔案開啟模式 -> 到例項屬性中 self.file_name = file_name self.file_model = file_model if __name__ == '__main__': with MyFile("hello.txt", "r") as file: # 開始讀取檔案 file_data = file.read() print(file_data)
執行結果:
進入上文.... hello,python! 進入下文....
__enter__()
⽅法返回資源物件,這⾥就是你將要開啟的那個⽂件物件,__exit__()
⽅法做⼀些清除⼯作。
因為 File 類實現了上下⽂管理器,所以就可以使⽤ with 語句了。
二、實現上下⽂管理器的另外⽅式
Python 提供了⼀個 contextmanager 模組的裝飾器@contextmanager
,更進⼀步簡化了上下⽂管理器的實現⽅式。通過 yield 將函式分割成兩部分,yield 之前的語句在__enter__ ()
⽅法中執⾏,yield 之後的語句在__exit__()
⽅法中執⾏。緊跟在 yield 後⾯的值是 函式的返回值。
裝飾器:不修改(待修飾函式)原函式的程式碼,增加新的功能(方法)
""" 思路: def myopen(file_name,file_model) 上文(開啟資源) yield 下文(關閉資源) 裝飾器裝飾函式的步驟: 1. 匯入模組 from contextlib import contextmanager 2. 開始裝飾 @contextmanager """ from contextlib import contextmanager @contextmanager def myopen(file_name,file_model): print("進入上文") # 1.開啟檔案 file = open(file_name,file_model) # 2.返回資源 yield file print("進入下文") # 下文 # 3. 關閉資源 file.close() with myopen("hello.txt", "r") as file: file_data = file.read() print(file_data)
執行結果:
進入上文.... hello,python! 進入下文....
五、 總結
1)Python 提供了 with 語法⽤於簡化資源操作的後續清除操作,實現原理建⽴在上下⽂管理器協議 (__enter__
和__exit__
)之上
2)with使⽤程式碼中如果在開啟過程中發⽣異常,需要使⽤try-except進⾏捕獲
3)Python 還提供了⼀個 contextmanager 裝飾器,更進⼀步簡化上下管理器的實現⽅式。
六、應用with open() as
1.建立 寫檔案
request_data = urllib.request.urlopen(img_url) #在(指定路徑下 )--> 建立檔案 --> 準備儲存 with open('/home/cfl/Desktop/” + file_name, "wb") as file: #在(當前目錄) --> 建立檔案 --> 準備儲存 with open(file_name, "wb") as file: while True: file_data = request_data.read(1024) if file_data: file.write(file_data) else: break
2.開啟 讀檔案
recv_data = new_client_socket.recv(1024)
file_name = recv_data.decode()
#根據檔名讀取檔案內容
try:
with open(file_name, “rb”) as file:
把讀取的檔案內容傳送給客戶端(迴圈)
while True:>
file_data = file.read(1024)
判斷是否讀取到了檔案的末尾
if file_data:
傳送檔案
new_client_socket.send(file_data)
else:
break
except Exception as e:
print(“檔案%s下載失敗” % file_name)
else:
print(“檔案%s下載成功” % file_name
相關文章
- Python - Context Manager 上下文管理器PythonContext
- odoo context上下文用法總結OdooContext
- 什麼是Python中Context上下文管理器PythonContext
- React中的Context和Portals用法ReactContext
- React的上下文-ContextReactContext
- go 上下文:context.ContextGoContext
- iris 路由註冊和上下文context路由Context
- 程式中的context(上下文)Context
- pythonic context manager知多少PythonContext
- Go進階01:golang context 上下文用法詳解(比較好理解)GolangContext
- Python中的上下文管理器Python
- React context基本用法ReactContext
- Golang context (上下文)是什麼GolangContext
- Pyhton提高:with上下文管理器
- virt-manager cannot open display問題
- sys_context函式的用法Context函式
- CSS 層疊上下文(Stacking Context)CSSContext
- 上下文 Context 與結構體 StructContext結構體Struct
- 上下文管理器與 with 語句
- SYS_CONTEXT函式的用法(ZT)Context函式
- 雅虎開源的Kafka叢集管理器(Kafka Manager)Kafka
- CoreData 手動自動 建立context(上下文)Context
- 獲取管理中心上下文ContextContext
- Python深入02 上下文管理器Python
- Python分享之上下文管理器Python
- sys_context函式用法Context函式
- Python學習之路33-上下文管理器和else塊Python
- sys_context 獲取環境上下文的函式Context函式
- python上下文管理器closing的應用Python
- 【原創】SYS_CONTEXT函式的用法Context函式
- Python 簡單理解 with 上下文管理器Python
- Android中Context用法詳解AndroidContext
- 資料庫資源管理器(Database Resource Manager)資料庫Database
- Python 的上下文管理器是怎麼設計的?Python
- 一起學context(一)——上下文值傳遞Context
- [Dynamic Language] Python Django: 模板引擎(2)上下文ContextPythonDjangoContext
- 鴻蒙HarmonyOS實戰-Stage模型(應用上下文Context)鴻蒙模型Context
- 完全理解關鍵字”with”與上下文管理器