歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Python學(xué)習(xí)之上下文管理器詳解

發(fā)布時間:2018-04-22 22:06  回復(fù):0  查看:2608   最后回復(fù):2018-04-22 22:06  
本文和大家分享的是python 中上下文管理器相關(guān)內(nèi)容,上下文管理器主要用于規(guī)定某個對象的使用范圍,下面將詳細(xì)圍繞上下文管理器使用方法、實(shí)現(xiàn)機(jī)制等方面展開介紹,一起來看看吧,希望對大家 學(xué)習(xí)python有所幫助。
   為什么需要上下文管理器?
  首先,需要思索下為什么需要引入上下文管理器。
  在正常情況下,管理各種系統(tǒng)資源(如文件)、數(shù)據(jù)庫連接時,通常是先打開這些資源,執(zhí)行完相應(yīng)的業(yè)務(wù)邏輯,最后關(guān)閉資源。
  舉兩個例子:
  1.  使用 Python 打開一個文件寫入內(nèi)容,之后需要關(guān)閉這個文件。如果不正常關(guān)閉的話可能會在文件操作時出現(xiàn)異常,因?yàn)橄到y(tǒng)允許你打開的文件的最大數(shù)是有限的。
  2.  在數(shù)據(jù)庫連接時也是存在類似問題,數(shù)據(jù)庫的連接算是一種比較昂貴的資源,若連接過多而沒有及時關(guān)閉的話,就可能出現(xiàn)不能繼續(xù)連接的異常錯誤。
  但是,很多程序員經(jīng)常會忘記關(guān)閉文件,或者關(guān)閉數(shù)據(jù)庫的連接。這時候就引入了  上下文管理器  ,它可以在你不需要該對象的時候,自動關(guān)閉它。
   上下文管理器怎么使用?
  上下文管理器的語法是:with...as...
   實(shí)例:文件操作
   print " 不使用上下文管理器 " print "*" * 30 f =  open('file.py', 'w') print  f.closed f. write("# Hello World") f. close() print  f.closed
   print "\n 使用上下文管理器 " print "*" * 30
  with  open("file.py", 'w')  as  f:
   print  f.closed
   f. write('# Hello Python') print  f.closed
  這里通過.closed 比較,我們可以看到上下文管理器可以自動關(guān)閉文件,對于上下文管理器而言,有隸屬于它的程序塊,當(dāng)隸屬于它的程序塊執(zhí)行結(jié)束的時候(判斷縮進(jìn)),上下文管理器將自動關(guān)閉文件。
  上述實(shí)例,也可以使用try...except... 來實(shí)現(xiàn),同樣可以很直觀的看到使用 with...as... 語句之后,代碼確實(shí)相對更加簡潔。
   上下文管理實(shí)現(xiàn)機(jī)制
  因?yàn)槲募ο笫?/span>Python 的內(nèi)置對象,內(nèi)置了上下文管理的特殊方法,所以它可以使用 with 語句。在 Python 中,任何對象,只要實(shí)現(xiàn)了上下文管理,就可以使用 with 語句,實(shí)現(xiàn)上下文管理需要通過 __enter__ __exit__ 這兩個方法來實(shí)現(xiàn)。
  關(guān)于這兩個方法:
  ·  enter (self) :進(jìn)入該對象時調(diào)用此方法,返回值將放入 with...as... 語句中的 as 說明的變量中
  ·  exit (self, type, value, tb): 離開上下文管理器時調(diào)用該方法,如果有異常出現(xiàn),返回 False , type 、 value tb 將分別表示異常的類型、值和追蹤信息,傳遞出上下文顯示;如果沒有異常,則三個變量的值均為 None 。
   with  上下文管理器:
  語法體
  當(dāng)with 語句遇到上下文管理器時,就會在執(zhí)行語法體之前,先執(zhí)行 __enter__ 方法,然后再執(zhí)行語法體,執(zhí)行完語法體之后,執(zhí)行 __exit__ 方法。
   上下文管理器實(shí)現(xiàn)
  使用Python2.7X 實(shí)現(xiàn)一個上下文管理器 :
   class  Context(object):
   def  __init__(self):
   print " 實(shí)例化一個對象 "
   def  __enter__(self):
   print " 獲取該對象 "
   def  __exit__(self, exc_type, exc_val, exc_tb):
   print " 退出該對象 "
  temp = Context()
   with temp:
   print " 執(zhí)行體 "
  這樣,__enter__ 方法和 __exit__ 方法的調(diào)用過程就很明晰。
  contextLib
  在contextlib 中,提供了 contextmanager 裝飾器,通過 yield 返回函數(shù)將函數(shù)分隔為兩部分, yield 之前的語句在 __enter__ 中執(zhí)行, yield 之后的語句在 __exit__ 中執(zhí)行,簡化了上下文管理器的實(shí)現(xiàn)方式:
總結(jié):通過上下文管理器,我們可以更好的控制對象在不同區(qū)間的特性,并且可以使用with 語句替代 try...except 方法,使得代碼更加的簡潔,主要的使用場景是訪問資源,可以保證不管過程中是否發(fā)生錯誤或者異常都會執(zhí)行相應(yīng)的清理操作,釋放出訪問的資源。
來源:網(wǎng)絡(luò)
您還未登錄,請先登錄

熱門帖子

最新帖子

?