丨巧用上下文管理器和with語句精簡代碼_第1頁
丨巧用上下文管理器和with語句精簡代碼_第2頁
丨巧用上下文管理器和with語句精簡代碼_第3頁
丨巧用上下文管理器和with語句精簡代碼_第4頁
丨巧用上下文管理器和with語句精簡代碼_第5頁
已閱讀5頁,還剩12頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

在任何一門編程語言中,文件的輸入輸出、數據庫的連接斷開等,都是很常見的資源管理操作。但資源都是有限的,在寫程序時,須保證這些資源在使用過后得到釋放,不然就容易造成資源,輕者使得系統處理緩慢,重則會使系統。光說這些概念,你可能體會不到這一點,我們下面的例子代forxin f=open('test.txt', 代OSError:[Errno23]Toomanyopenfilesinsystem:源,造成系統。為了解決這個問題,不同的編程語言都引入了不同的機制。而在Pyhon中,對應的解決方式便是上下文管理器(conetmaaer)。上下文管理器,能夠幫助你自動分配并且釋放資源,其中最典型的應用便是with語句。所以,上面代碼的正確寫法應該如下所示:代forxin withopen('test.txt','w')as 相應的資源也可以得到釋放,防止資源。當然,with語句的代碼,也可以用下面的式表示代f=open('test.txt',要注意的是,最后的finallyblock尤其重要,哪怕在寫入文件時發生錯誤異常,它也可以保證該文件最終被關閉。不過與with語句相比,這樣的代碼就顯得冗余了,并且還容易漏寫,因此我們一般更傾向于使用with語句。另外一個典型的例子,是Python中的threading.lock類。舉個例子,比如要獲取一代some_lock=而對應的with語句,同樣非常簡代some_lock=with我們可以從這兩個例子中看到,with語句的使用,可以簡化了代碼,有效避免資源的基于類的上下的原理,搞清楚它的內部實現。這里,我自定義了一個上下文管理類FileManager,模擬Python的打開、關閉文件操作:代class init(self,name, =self.mode=self.file=7 enter self.file=open(,returnexit(self,exc_type,exc_val, ifwithFileManager('test.txt','w')asprint('readytowritetof.write('o##

readytowriteto 需要注意的是,當我們用類來創建上下文管理器時,必須保證這個類包括方法 _()”和方法“exit()”。其中,方法“enter()”返回需要被管理的資源,方法“exit()”里通常會存在一些釋放、清理資源的操作,比如這個例子中的關閉文件而當我們用with語句,執行這個上下文管理器代withFileManager('test.txt','w')asf.write('o下面這四步操作會依次發生方法“init()”被調用,程序初始化對象FileManager,使得文件名(name)是"test.txt",文件模式(mode)是'w';方法“enter()”被調用,文件“test.txt”以寫入的模式被打開,并且FileManager象賦予變量字符串 oworld”被寫入文件方法“exit()”被調用,負責關閉之前打開的文件流因此,這個程序的輸出是代

readytowriteto exit()”中的參數“exc_type,exc_val,exc_tb”,分別表示exception_type、exception_value和traceback。當我們執行含有上下文管理器的with語句時,如果有異常拋出,異常的信息就會包含在這三個變量中,傳入方法“exit()” exit()”添加相應的代碼,比如下代class273456print(' ')89exit(self,exc_type,exc_value,print(' ifprint(f'exc_type:print(f'exc_value:print(f'exc_traceback:print('exceptionreturnwithFoo()asraiseException('exception#輸 exc_type:<classexc_value:exceptionexc_traceback:<tracebackobjectat exception這里,我們在with語句中手動拋出了異常“exceptionraised”,你可以看到,“ ()”方法中異常,被順利捕捉并進行了處理。不過需要注意的是,如果方法“exit 沒有返回True,異常仍然會被拋出。因此,如果你確定異常已經被處理了,請在“exit()”的最后,加上“returnTrue”這條語句。代class23456789meself.port= self.connection=None enter self.connection=DB (self.hostname,self.port)returnself( exit(self,exc_type,exc_val, f,,):.=14withDBConnectionManager('localhost','8080')asdb_與前面FileManager的例子類似方法“init()”負責對數據庫進行初始化,也就是將主機名、接口(這localhost8080)分別賦予變量hostname方法“enter()”連接數據庫,并且返回對象DBConnectionManager;方法“exit()”則負責關閉數據庫的連接。這樣一來,只要你寫完了DBconnectionManager這個類,那么在程序每次連接數據庫時,我們都只需要簡單地調用with句即可,并不需要關心數據庫的關閉、異常等等,顯基于的上下文管理誠然,基于類的上下文管理器,在Python中應用廣泛,也是我們經常看到的形式,不過Python中的上下文管理器并不局限于此。除了基于類,它還可以基于實現。接下來比如,你可以使用裝飾器contextlib.contextmanager,來定義自己所需的基于的上下文管理器,用以支持with語句。還是拿前面的類上下文管理器FileManager來說,代1fromcontextlibimport2deffile_manager(name,f=open(name,yieldwithfile_manager('test.txt','w')asf.write('o這段代碼中,函數file_manager()是一個,當我們執行with語句時,便會打開文件,并返回文件對象f;當with語句執行完后,finallyblock中的關閉文件操作便會執你可以看到,使用基于的上下文管理器時,我們不再用定義“enter()”和exit()”方法,但請務必加上裝飾器@contextmanager,這一點新手很容易疏基于類的上下文管理器更 flexible,適用于大型的系統開發而基于的上下文管理器更加方便、簡潔,適用于中小型程序 exit()”或者是finallyblock中釋放資源,這節課,我們先通過一個簡單的例子,了解了資源的易發生性,和其帶來的嚴重,從而引入了應對方案——即上下文管理器的概念。上下文管理器,通常應用在文件的打開關閉和數據庫的連接關閉等場景中,可以確保用過的資源得到迅速釋放,有效提高了程序的安全性,接著,我們通過自定義上下文管理的實例,了解了上下文管理工作的原理,并一起學習了基于類的上下文管理器和基于的上下文管理器,這兩者的功能相同,具體用哪個,取決于你的具體使用場景。另外,上下文管理器通常和with語句一起使用,大大提高了程序的簡潔度。需要注意的是,當我們用with語句執行上下文管理器的操作時,一旦有異常拋出,異常的類型、值等具體信息,都會通過參數傳入“exit()”函數中。你可以自行定義相關的操作對異常進行處理,而處理完異常后,也別忘了加上“returnTrue”這條語句,否則仍然會拋出異那么,在你日常的學習工作中,哪些場景使用過上下文管理器?使用過程中又遇到了哪些問題,或是有什么新的發現呢?歡迎在下方留言與我討論,也歡迎你把這篇文章出去,我們一起交流,一起進步。?歸科技所有 不得售賣。頁面已增加防盜追蹤,將依法其上一 28|如何

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論