在我閱讀python核心程式設計有關with語句的部分時,我沒有弄懂到底講了什麼?with語句能帶來什麼好處?後來對它的理解逐漸清晰了起來,所以本文便想談一談我對with語句現在的理解,本篇文章之後還會再次更新。
我把with語句理解為對try,except和finally的一種封裝。使用with語句可以讓程式結構看似更簡單,避免**重複,更加pythonic。with語句僅能工作於支援上下文管理協議的物件,即該物件必須實現__enter__與__exit__方法。
with 表示式[ as 變數]:
with子語句塊
具體例子,如開啟檔案並列印:
with open('/path/to/file','r') as file:
for line in file:
print line,
上述**在執行完畢時能自動關閉檔案,無論是否有異常;甚至通過修改,我們可以讓with自動處理異常。總之,with可以讓我們把注意力從惦記著釋放資源,處理異常等瑣事上更多地轉移到如何更好的寫**,使程式更高效。
這部分可以結合上面with語句結構來看。
首先,with對其後的表示式進行求值,該表示式會返回乙個物件,該物件一定包含__enter__與__exit__兩個特殊方法。該物件一旦被返回,會立即自動呼叫__enter__方法,該方法返回的結果會被賦值給as關鍵字後的變數。此處注意,with後表示式的結果並沒有賦值給變數,是__enter__方法的返回值被賦給了該變數。
with語句表示式的作用是返回乙個遵循上下文管理協議的物件,即該物件必須實現__enter__與__exit__方法。
1)形式:__enter__(self)
2)該方法主要負責在with子語句塊執行前進行一些配置。
3)表示式返回結果物件時,立即呼叫返回物件的該方法。如果表示式後有as關鍵字,該方法的返回值被賦值給as後的變數;如果沒有as關鍵字,則該方法的返回值被拋棄。
1)形式:__exit__(self, exc_type, exc_instance, traceback),3個引數分別表示異常型別,異常例項,回溯函式。如果with子句沒有發生異常,3個引數全部為none;但一旦發生異常,3個引數便會被填充。
2)該方法在整個with語句塊執行完畢後執行,用於釋放資源或處理異常等。即使with子語句塊內發生了異常,該方法也一定會執行。
3)當with子語句塊發生異常時,會立即執行__exit__方法,__exit__方法可以選擇是否處理並「包庇」該異常。當__exit__方法返回為true時,python直譯器會繼續執行with語句後面的**(注意,with子語句塊內的後面**不會被執行),返回false時,則丟擲該異常。
最後舉乙個用到的例子,有關於資料庫的(mysqldb是第三方模組,可通過「pip install mysql-python」安裝):
#!/usr/bin/env python
# coding=utf-8
import mysqldb
class sqltool(object):
def __init__(self, db, user='資料庫使用者', pwd='資料庫密碼', host='localhost', port=3306):
self.connect = mysqldb.connect(user=user, passwd=pwd, host=host, port=port, db=db) # 建立資料庫連線
self.cursor = self.connect.cursor() # 建立游標
def __enter__(self):
return self.cursor # 返回游標給with語句的cursor變數
def __exit__(self, exc_type, exc_instance, traceback):
if exc_instance:
print exc_instance
self.cursor.close() # 關閉游標
self.connect.commit() # 確認提交
self.connect.close() # 關閉連線
return true # with語句發生的所有異常都不丟擲
with sqltool(db='test') as cursor:
cursor.execute('insert into people(name, age) values (%s, %s)', ('jinixin', 20))
參考自python核心程式設計第二版10.4節,python高階程式設計第2章
文中如有不恰當的地方,還望包容和指出,感謝
python上下文管理
重寫 enter 方法,返回值會被 as 捕獲 重寫 exit 方法 democlass mycontextmanager def enter self print 進入管理器範圍執行方法 此處的返回值會被 with xx as 捕獲 return 退出上下文管理範圍執行方法,即使中間報錯也會執行 ...
python 高階 with 上下文管理
with 上下文管理器 語法糖 python 提供的一種簡化語法,在編寫 時更加簡潔 with 就是眾多語法糖中的一種 with 執行原理 能通過with進行執行的語句,都是實現了上下文管理器 上下文管理器中包含兩個魔法方法 enter 和 exit enter 方法提供環境的初始化操作 exit ...
python 上下文管理協議
class open def init self,name self.name name def enter self print 出現with語句,物件的 enter 被觸發,有返回值則賦值給as宣告的變數 return self def exit self,exc type,exc val,ex...