2013-05-27 32 views
1

下面是一個假設的一段代碼如何使用Python中的上下文管理器來

with dbengine.connect(**details) as db: 
    cur = db.exec(sql_string) 
    results = cur.fetchall() 
return results 

在這種情況下,我會期望標籤出與塊db.close()時被調用和db被標記爲垃圾收集。

在工作中,我已經開始看到這段代碼出現了。

with something() as myobj: 
    logger.info('I got an obj!') 
return myobj 

我不知道你是否應該使用象Java中關鍵字。有人能指導我找到任何可以解釋在使用時可以/不應該做什麼的好文檔嗎?

P.S日誌消息實際上是跛腳:-)

+1

第二段代碼完全沒有意義。擊中寫它的人。打他很難。 – 2013-05-27 14:02:26

回答

2

目標名稱with聲明綁定contextmanager __enter__返回值as後的名稱)沒有作用域只是with聲明。與for循環變量類似,as目標名稱在當前函數或模塊名稱空間中作用域。當with套件結束時,名稱不會消失或以其他方式清除。

因此,return myobjwith聲明是完全合法的,如果有點荒謬。 with聲明保證的是,在塊完成時(即通過到達塊的末尾,或者由於continuebreakreturn語句或因爲引發異常),將調用something().__exit__()方法。

這就是說,你會更好,只是移動回with聲明:

with something() as myobj: 
    logger.info('I got an obj!') 
    return myobj 

with dbengine.connect(**details) as db: 
    cur = db.exec(sql_string) 
    return cur.fetchall() 

上下文管理器仍然會正確清理,但現在return語句看起來像是with塊的邏輯部分。執行順序不變;調用something().__exit__(),則函數返回。

一如既往,Python documentation on the with syntax非常出色。您也可以查看documentation on context managersoriginal proposal, PEP-343

相關問題