Python基础教程: with语句详解
with語句的應用場景
編程中有很多操作都是配套使用的,這種配套的流程可以稱為計算過程,Python語言為這種計算過程專門設計了一種結構:with語句。比如文件處理就是這類計算過程的典型代表。
使用with語句前后對比
沒有使用with語句之前,我們是這樣打開一個文件的:
try:# 1. [進入]f = open('a.txt', 'r', encoding="utf-8")# 2. [執行]print(f.read()) finally:if f:# 3. [退出]f.close()python操作文件的流程一般就是這三步:
如果文件不存在,open()函數就會拋出一個IOError的錯誤,并且給出錯誤碼和詳細的信息告訴你文件不存在
如果文件打開成功,接下來,調用read()方法可以一次讀取文件的全部內容,Python把內容讀到內存,用一個str對象表示
文件使用完畢后必須關閉,因為文件對象會占用操作系統的資源,并且操作系統同一時間能打開的文件數量也是有限的
思考為什么關閉文件操作一定要放在finallly語句里?
由于文件讀寫時都有可能產生IOError,一旦出錯,后面的f.close()就不會調用。所以,為了保證無論是否出錯都能正確地關閉文件,我們可以使用try … finally來實現。
發現共性:
我們發現其實這種過程化的語句有共性,比如說在進去一個片段前必須做某種超贊,處理工作后又需要執行一個結束操作。比如上面的這段代碼:
finally:if f:f.close()上面的代碼塊就可以做一個封裝。
使用with語句后,我們是這樣打開一個文件的:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' with open("a.txt", "r", encoding="utf-8") as f:print(f.read())這個with語句和前面的try … finally結構是一樣的,但是代碼更佳簡潔,并且不必調用f.close()方法。
with語句的執行原理
從解釋器的角度去理解with語句執行流程。
with語句的基本形式是:
with 表達式 as 變量:語句塊這樣的一段代碼可以稱為一個上下文(context),在執行with語句時,解釋器會先求出表達式的值,這個值(對象)是一個上下文管理器,并且假設這個對象擁有如下兩個類魔術方法:
def __enter__():# 描述進入上下文的動作passdef __exit__():# 描述退出上下文的動作passwith語句在求出這個上下文管理器對象之后,自動執行進入方法,并將這個對象的返回值賦值于 as 之后的變量,然后執行語句塊。然后在退出上下文前,自動執行對象的退出方法。
python系統和標準庫的一些類型定義了這對操作,可以直接用于with語句。比如文件對象就直接支持這一對操作,因此可以用在with語句的頭部。
如果你也有類似的計算過程需要抽取出來,那么可以自定義一個類,并且包含進入、退出方法。
自定義open函數
自己實現才發現,使用裝飾器和生成器就能很好的解決這個問題,不需要用到類魔術方法來實現;
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' import contextlib # 引入上下文管理包@contextlib.contextmanager # 給函數引入裝飾器 def myopen(dir, mode):print("開始")f = open(dir, mode, encoding='utf-8')try: # 上文yield ffinally: # 下文print("結束")f.close()with myopen("a.txt", 'r') as fobj: # 把try中的yield中的f賦值給fobj# with會將with后面的函數中的yield賦值給fobjfor i in fobj:print(i)# 等待上面的循環結束后,才最終執行finally的代碼,所以這就是上下文管理輸出:
開始 hello,我是a.txt的第1行文字。 結束總結
打開文件讀寫、用pickle包完成數據的存儲、恢復的操作,都非常適合使用with語句。
pickle包的使用案例:
try:with open("phone.pickle", "wb") as outf:pickle.dump("13193388105", outf) except:print("file have errow.")try:with open("phone.pickle", "rb") as outf:data = pickle.load(outf)print(type(data))print(data) except:print("file have errow.")我總結了一下使用with語句的優點:
-
采用with語句的代碼更簡潔;
-
防止因為忘記寫f.close()而引發的錯誤;
-
一個對象(上下文)的操作有進入、退出過程就可以抽取出來,并做成自動化執行;
總結
以上是生活随笔為你收集整理的Python基础教程: with语句详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python如何使用不同分隔符切分字符串
- 下一篇: Python基础教程:回调在编程中的含义