python-with語句
with 語句適用於對資源進行訪問的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如檔案使用後自動關閉、執行緒中鎖的自動獲取和釋放等。
淺顯得講就是使用with語句,會自動幫我們在執行結束後進行清理,注意即使中途丟擲異常,一樣會進行清理,有點像unitest中 teardown的意思
舉個最常見得例子:
####不使用with語句f=open("my.log","r")try: lines=f.readlines()except Exception as e: raise efinally: f.close()####使用with語句with open("my.log","r") as f: lines=f.readlines()
如果不適用with語句需要在我們不使用檔案得時候手動去關閉檔案,而with則不用,會自動幫我們處理,不管執行成功或者失敗
透過例子我們可以大致看出來with語句得語法格式
with context_expression [as something]: with-body
需要注意with語句操作得物件必須具有上下文管理器,也就是需要具有__ enter__方法,__ exit__方法
__enter __:入口方法,執行在with-body之前
__exit __:退出清理方法,執行在with-body之後
剛剛得例子雖然能說明問題,但是看得不夠直觀,我們來建立一個具有上下文管理器得物件
class my(): def __enter__(self): print("i am enter") def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit")with my() as haha: print("i am with body")###輸出i am enter i am with body i am exit
上面得例子可以看出所有得執行過程,但是並沒有體現出在with body中出錯後會執行exit方法,來看下面得例子:
class my(): def __enter__(self): print("i am enter") def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit")with my() as haha: print("i am with body"+1)###輸出i am enter Traceback (most recent call last): File "/Users/hjc/workspace/myutils/meiyouyong.py", line 8, in <module> i am exit print("i am with body"+1) TypeError: must be str, not int i am exit
可以看到exit方法被執行了,但是這裡有個bug,如果我們給my類加個成員方法,這時haha找不到該方法
class my(): def __enter__(self): print("i am enter") def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit") def run(self): print("i am run")with my() as haha: haha.run()###執行結果i am enter Traceback (most recent call last): File "/Users/hjc/workspace/myutils/meiyouyong.py", line 10, in <module> haha.run() AttributeError: 'NoneType' object has no attribute 'run'i am exit
上面得例子很明顯haha並沒有run方法,這是為什麼呢,我們再看一下下面得例子
class my(): def __enter__(self): print("i am enter") def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit") def run(self): print("i am run")with my() as haha: my().run()###執行結果i am enter i am run i am exit
我們把haha改成了my()就可以了,為什麼haha作為my()得替代沒有呢,原因是my()先執行得是enter方法,而enter並沒有返回值,導致haha替代my()時為None,自然沒有run()方法
class my(): def __enter__(self): print("i am enter") def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit") def run(self): print("i am run")with my() as haha: print(haha)###執行結果i am enterNonei am exit
找到問題得原因就簡單了,我們只要執行enter時候把物件返回就好了
class my(): def __enter__(self): print("i am enter") return self #將物件返回 def __exit__(self, exc_type, exc_val, exc_tb): print("i am exit") def run(self): print("i am run")with my() as haha: haha.run()###執行結果i am enter i am run i am exit
作者:MR_Hanjc
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2768/viewspace-2819030/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- flask之控制語句 if 語句與for語句Flask
- 分支語句和迴圈語句
- 【SQL】14 UNION 操作符、SELECT INTO 語句、INSERT INTO SELECT 語句、CREATE DATABASE 語句、CREATE TABLE 語句SQLDatabase
- if 語句
- if語句
- insert into select語句與select into from語句
- Linux下邏輯測試語句引數和流程控制語句 if語句Linux
- Java中如何解析SQL語句、格式化SQL語句、生成SQL語句?JavaSQL
- JavaScript 語句JavaScript
- 衛語句
- JavaScript for in 語句JavaScript
- if衛語句
- 控制語句
- break語句
- MySQLDELETE語句MySqldelete
- 語句排序排序
- mysql語句MySql
- SQL語句SQL
- Python-條件語句和迴圈語句Python
- JavaScript 流程控制語句詳解:if語句、switch語句、while迴圈、for迴圈等JavaScriptWhile
- c語言中,while(1)語句使用break語句跳出迴圈C語言While
- ORACLE 資料庫 查詢語句與DML語句Oracle資料庫
- SQL SELECT 語句SQL
- Java 控制語句Java
- JavaScript return 語句JavaScript
- JavaScript while 語句JavaScriptWhile
- mySql常用語句MySql
- js的with語句JS
- MySQL的語句MySql
- 常用MSSQL語句SQL
- JavaScript switch語句JavaScript
- JavaScript if else 語句JavaScript
- JavaScript switch 語句JavaScript
- JS note ---語句JS
- RHCE(ansible語句)
- sql常用語句SQL
- oracel常用語句
- Matlab常用語句Matlab