本問題已經有最佳答案,請猛點這里訪問。
我是Python的新手。在一個關于連接到MySQL和獲取數據的教程中,我看到了with語句。我讀到它,它與try-finally塊有關。但我找不到一個我能理解的更簡單的解釋。
stackoverflow.com/questions/3012488/…
with語句打開一個資源,并保證當with塊完成時,無論該塊如何完成,都將關閉該資源。考慮一個文件:
with open('/etc/passwd', 'r') as f:
print f.readlines()
print"file is now closed!"
即使您有一個return,即使您引發異常,文件也保證在塊的末尾關閉。
為了使with作出此保證,表達式(示例中的open()必須是上下文管理器。好消息是,許多Python表達式都是上下文管理器,但不是全部。
根據我發現的一個教程,MySQLdb.connect()實際上是一個上下文管理器。
此代碼:
conn = MySQLdb.connect(...)
with conn:
cur = conn.cursor()
cur.do_this()
cur.do_that()
將作為單個事務提交或回滾命令序列。這意味著您不必太擔心異常或其他異常代碼路徑——不管您如何離開代碼塊,事務都將得到處理。
從根本上講,它是一個對象,它用在入口和出口調用的自定義邏輯來劃分代碼塊,并且可以在其構造中接受參數。可以使用類定義自定義上下文管理器:
class ContextManager(object):
def __init__(self, args):
pass
def __enter__(self):
# Entrance logic here, called before entry of with block
pass
def __exit__(self, exception_type, exception_val, trace):
# Exit logic here, called at exit of with block
return True
然后入口被傳遞一個ContextManager類的實例,并且可以引用在__init__方法(文件、套接字等)中創建的任何內容。exit方法還接收在內部塊和堆棧跟蹤對象或None中引發的任何異常(如果邏輯完成而沒有引發)。
然后我們可以這樣使用它:
with ContextManager(myarg):
# ... code here ...
這對于管理資源生命周期、釋放文件描述符、管理異常以及構建嵌入式DSL等更復雜的用途都很有用。
另一種(但等效的)構造方法是contextlib裝飾器,它使用一個生成器來分離出入口邏輯。
from contextlib import contextmanager
@contextmanager
def ContextManager(args):
# Entrance logic here
yield
# Exit logic here
把with看作是在代碼塊上創建一個"主管"(上下文管理器)。甚至可以給主管一個名稱并在塊中引用。當代碼塊正常結束或通過異常結束時,會通知主管,主管可以根據發生的情況采取適當的措施。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态