【Python】【控制流程程】【二】【上下文管理器】

來源:互聯網
上載者:User

標籤:工具   for   協議   operation   複合   猴子補丁   origin   import   ace   

"""
#[備忘]
#1??try :僅當try塊中沒有異常拋出時才運行else塊。
#2??for:僅當for迴圈運行完畢(即for迴圈沒有被break語句終止)才運行else
#while:僅當while迴圈因為條件為假植而退出時(即while迴圈沒有被break語句終止)才運行else
#即在所有情況下,如果異常或者return、break、或continue語句導致控制權跳到了複合陳述式的主塊之外,else子句也會被跳過

#15。2 上下文管理器和with塊
#上下文管理協議包含__enter__和__exit__兩個方法。with語句開始運行時,會在上下文管理器對象上調用__enter__方法。with語句運行結束後,會在上下文管理器對象上調用__exit__方法,以此扮演finally子句的角色
#例子15-1
with open(‘__init__.py‘) as fp:
src = fp.read(60)
print(len(src)) #4
print(fp) #<_io.TextIOWrapper name=‘__init__.py‘ mode=‘r‘ encoding=‘UTF-8‘>
print(fp.closed,fp.encoding) #True UTF-8
print(fp.read(60)) #ValueError: I/O operation on closed file.

#例子15-2 強調上下文管理器與__enter__方法返回的對象之間的區別
class LookingClass:
def __enter__(self):# 除了SELF外,python調用__enter__方法時不傳入其他參數
import sys
self.original_write = sys.stdout.write #往標準輸出裡寫入資料,相當於print
sys.stdout.write = self.reverse_write #為sys.stdout.write打猴子補丁
return ‘JABBERWOCKY‘
def reverse_write(self,text):
self.original_write(text[::-1])
def __exit__(self, exc_type, exc_val, exc_tb): #exc_type 異常類(例如ZeroDivisionError)exc_value 異常執行個體。有時會有參數傳給異常構造方法,例如錯誤訊息,這些參數可以使用exc_value.args擷取 traceback :traceback對象。
import sys # 重複倒入模組不會消耗很多資源,因為python會緩衝有匯入的模組
sys.stdout.write = self.original_write #還原原來的sys.stdout.write方法
if exc_type is ZeroDivisionError:
print(‘Please DO NOT divide by zero!‘)
return True #告訴解譯器,異常已經解決
#如果__exit__方法返回None,或者True之外的值,with塊中的任何異常都會向上冒泡
with LookingClass() as what: #上下文管理器是LookingClass類的執行個體,python在上下文管理器上調用__enter__方法,把結果綁定到what上
print(‘Alice,Kigtty and Snowdrop‘) #pordwonS dna yttgiK,ecilA
print(what) #YKCOWREBBAJ
print(what) #JABBERWOCKY 輸出不再反向
print(‘Back to normal.‘) #Back to normal. 輸出不再反向
#例子15-4 在with塊之外使用LookingClass類
manager = LookingClass()
print(manager) #<__main__.LookingClass object at 0x10d593be0>
monster = manager.__enter__()
print(monster == ‘JABBERWOCKY‘) #eurT
print(monster) #YKCOWREBBAJ
print(manager) #>8abfca001x0 ta tcejbo ssalCgnikooL.__niam__<
manager.__exit__(None,None,None)
print(monster) #JABBERWOCKY


##15.3 contextlib模組中的工具 + 生產力
#closing :如果對象提供了close()方法,但沒有實現__enter__/__exit__協議,那麼可以實用這個函數構建上下文管理器
#suppress 構建臨時忽略指定異常的上下文管理器
#@contextmanager 這個裝飾器把簡單的產生器函數變成上下文管理器,這樣就不用建立類取實現管理器協議了
#15.4 使用@contextmanager
#例子15-5 使用產生器實現的上下文管理器
import contextlib

@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write

def reverse_write(text):
original_write(text[::-1])

sys.stdout.write = reverse_write
yield ‘JABBERWOCKY‘
sys.stdout.write = original_write
#例子15-6 測試
with looking_glass() as what:
print(‘Alice,Kitty and Snowdrop‘) #pordwonS dna yttiK,ecilA
print(what) #YKCOWREBBAJ
print(what) #JABBERWOCKY
#[分析]其實,contextlib.contextmanager 裝飾器會把函數封裝成實現__enter__和__exit__方法的類。這個類的__enter__方法有如下作用
#...1??調用產生器函數,儲存產生器對象(這裡把它稱為gen)
#...2??調用next(gen),執行到yield關鍵字所在的位置
#...3??返回next(gen)產出的值,以便把產出的值綁定到with/as語句中的目標變數上。
#...with 塊終止時,__exit__方法會作以下幾件事
#...1??檢查有沒有把異常傳給exc_type;如果有,調用gen.throw(exception),在產生器函數定義體中包含yield關鍵字的那一行拋出異常
#...2??否則,嗲用next(gen),繼續執行產生器函數定義體中yield之後的代碼
#【注意】上面的例子有一個嚴重的錯誤:如果發生異常,python解譯器會將其捕獲,然後在looking_glass函數的yield運算式裡再次拋出。但是,那裡沒有處理錯誤的代碼,因此looking_glass函數會中止,永遠無法恢複成原來的sys.stdout.write方法,導致系統處於無效狀態
# 例子15-7 基於產生器的上下文管理器,而且實現了異常處理-

"""

import contextlib
@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write

def reverse_write(text):
original_write([text[::-1]])

sys.stdout.write = reverse_write

msg = ‘‘
try:
yield ‘JABBERWOCKY‘
except ZeroDivisionError :
msg = ‘Please DO NOT divede by zero!‘
finally:
sys.stdout.write = original_write
if msg:
print(msg)
































【Python】【控制流程程】【二】【上下文管理器】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.