<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
如果你有閱讀原始碼的習慣,可能會看到一些優秀的程式碼經常出現帶有 with
關鍵字的語句,它通常用在什麼場景呢?對於系統資源如檔案、資料庫連線、socket 而言,應用程式開啟這些資源並執行完業務邏輯之後,必須做的一件事就是要關閉(斷開)該資源。
比如 Python 程式開啟一個檔案,往檔案中寫內容,寫完之後,就要關閉該檔案,否則會出現什麼情況呢?極端情況下會出現 Too many open files
的錯誤,因為系統允許你開啟的最大檔案數量是有限的。同樣,對於資料庫,如果連線數過多而沒有及時關閉的話,就可能會出現 Can not connect to MySQL server Too many connections
,因為資料庫連線是一種非常昂貴的資源,不可能無限制的被建立。
向檔案中寫入資料的範例程式碼(基礎):
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:25 # @Author : AmoXiang # @File : demo1.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 # 1、以寫的方式開啟檔案 f = open("1.txt", "w", encoding="utf8") # 2、寫入檔案內容 f.write("hello world") # 3、關閉檔案 f.close()
程式碼說明如下:檔案使用完後必須關閉,因為檔案物件會佔用作業系統的資源,並且作業系統同一時間能開啟的檔案數量也是有限的。這種寫法可能出現一定的安全隱患,錯誤程式碼如下:
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:25 # @Author : AmoXiang # @File : demo1.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 # 1、以寫的方式開啟檔案 f = open("1.txt", "r", encoding="utf8") # 2、寫入檔案內容 f.write("hello world") # 3、關閉檔案 f.close()
執行結果如下圖所示:
程式碼說明:由於檔案讀寫時都有可能產生 IOError
,一旦出錯,後面的 f.close()
就不會呼叫。為了保證無論是否出錯都能正確地關閉檔案,我們可以使用 try ... finally
來解決。安全寫法, 程式碼如下:
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:32 # @Author : AmoXiang # @File : demo2.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 try: # 1、以讀的方式開啟檔案 f = open("1.txt", "r") # 2、讀取檔案內容 f.write("xxxxx") except IOError as e: print("檔案操作出錯", e) finally: # 3、關閉檔案 f.close()
執行結果:
檔案操作出錯 not writable
這種方法雖然程式碼執行良好,但是缺點就是程式碼過於冗長,並且需要新增 try-except-finally
語句,不是很方便,也容易忘記。在這種情況下,Python 提供了 with 語句的這種寫法,既簡單又安全,並且 with 語句執行完成以後自動呼叫關閉檔案操作,即使出現異常也會自動呼叫關閉檔案操作。with 語句的範例程式碼:
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:34 # @Author : AmoXiang # @File : demo3.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 # 1、以寫的方式開啟檔案 with open("1.txt", "w") as f: # 2、讀取檔案內容 f.write("hello world") f.read() # 即使報錯,檔案資源也會關閉掉
一個類只要實現了 __enter__()
和 __exit__()
這個兩個方法,通過該類建立的物件我們就稱之為上下文管理器物件。上下文管理器可以使用 with 語句,with 語句之所以這麼強大,背後是由上下文管理器做支撐的,也就是說剛才使用 open 函數建立的檔案物件就是就是一個上下文管理器物件。自定義上下文管理器類,模擬檔案操作。定義一個 File 類,實現 __enter__()
和 __exit__()
方法,然後使用 with 語句來完成操作檔案, 範例程式碼:
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:38 # @Author : AmoXiang # @File : demo4.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 class File(object): # 初始化方法 def __init__(self, file_name, mode): # 定義變數儲存檔名和開啟模式 self.file_name = file_name self.mode = mode # 上文方法 def __enter__(self): print("進入上文方法") # 返回檔案資源 self.f = open(self.file_name, self.mode) return self.f # 下文方法 def __exit__(self, exc_type, exc_val, exc_tb): """ with 語句中,即使發生異常資訊,也會進入 __exit__ 中 :param exc_type: 發生異常時,異常的型別 :param exc_val: 發生異常時,異常的資訊 :param exc_tb: 異常物件,堆疊資訊 :return:如果返回False(程式碼沒有書寫返回值預設None,表示為False) 代表 異常發生以後,異常會繼續向外傳遞。如果返回True,代表異常不再向外傳遞 """ if exc_type: print("發生了異常......") return True print("進入下文方法") self.f.close() if __name__ == '__main__': with File("1.txt", "r") as file: content = file.read() print(content)
執行結果:
程式碼說明:
__enter__
表示上文方法,需要返回一個操作檔案物件__exit__
表示下文方法,with 語句執行完成會自動執行,即使出現異常也會執行該方法。上下文管理器的另外一種實現方式: 假如想要讓一個函數成為上下文管理器,Python 還提供了一個 @contextmanager
的裝飾器,更進一步簡化了上下文管理器的實現方式。通過 yield 將函數分割成兩部分,yield 上面的語句在 __enter__
方法中執行,yield 下面的語句在 __exit__
方法中執行,緊跟在 yield 後面的引數是函數的返回值。範例程式碼:
# -*- coding: utf-8 -*- # @Time : 2022-10-18 10:54 # @Author : AmoXiang # @File : demo5.py # @Software: PyCharm # @Blog : https://blog.csdn.net/xw1680 # 匯入裝飾器 from contextlib import contextmanager # 裝飾器裝飾函數,讓其稱為一個上下文管理器物件 @contextmanager def my_open(path, mode): try: # 開啟檔案 file = open(path, mode) # yield之前的程式碼好比是上文方法 yield file except Exception as e: print(e) finally: print("over") # yield下面的程式碼好比是下文方法 file.close() # 使用with語句 with my_open('out.txt', 'w') as f: f.write("hello , the simplest context manager")
Python 提供了 with 語句 用於簡化資源釋放的操作,使用 with 語句 操作建立在上下文管理器(實現 __enter__
和 __exit__
) 的基礎上。Python 還提供了一個 @contextmanager
裝飾器,更進一步簡化上下管理器的實現,讓一個函數可以成為上下文管理器,結合 with 語句 來使用。
到此這篇關於詳解Python中的with語句和上下文管理器的文章就介紹到這了,更多相關Python with語句和上下文管理器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45