對于系統資源如檔案、資料庫連接配接、socket 而言,應用程式打開這些資源并執行完業務邏輯之後,必須做的一件事就是要關閉(斷開)該資源。
比如 Python 程式打開一個檔案,往檔案中寫内容,寫完之後,就要關閉該檔案,否則會出現什麼情況呢?極端情況下會出現 "Too many open files" 的錯誤,因為系統允許你打開的最大檔案數量是有限的。
同樣,對于資料庫,如果連接配接數過多而沒有及時關閉的話,就可能會出現 "Can not connect to MySQL server Too many connections",因為資料庫連接配接是一種非常昂貴的資源,不可能無限制的被建立。
來看看如何正确關閉一個檔案。
普通版:
def m1():
f = open("output.txt", "w")
f.write("人生苦短,我用python")
f.close()
這樣寫有一個潛在的問題,如果在調用 write 的過程中,出現了異常進而導緻後續代碼無法繼續執行,close 方法無法被正常調用,是以資源就會一直被該程式占用者釋放。那麼該如何改進代碼呢?
進階版:
def m2():
f = open("output.txt", "w")
try:
f.write("人生苦短,我用python")
except IOError:
print("oops error")
finally:
f.close()
改良版本的程式是對可能發生異常的代碼處進行 try 捕獲,使用 try/finally 語句,該語句表示如果在 try 代碼塊中程式出現了異常,後續代碼就不再執行,而直接跳轉到 except 代碼塊。而無論如何,finally 塊的代碼最終都會被執行。是以,隻要把 close 放在 finally 代碼中,檔案就一定會關閉。
進階版:
def m3():
with open("output.txt", "r") as f:
f.write("人生苦短,我用python")
對于資料庫的操作也可以結合上下文管理器:
資料庫的操作分三步:
1.連接配接資料庫
2.sql執行語句
3.關閉連接配接
from pymysql import *
class DB(object):
def __init__(self, database_name, passward):
# 連接配接資料庫
self.conn = connect( host='localhost', port=3306, database= str(database_name), user='root', password=(passward),charset='utf8')
# 擷取cursor
self.cs1 =self.conn.cursor()
# self.sql = sql
# self.cs1.execute(self.sql)
def __enter__(self):
return self.cs1
def __exit__(self, *args):
self.cs1.close()
self.conn.close()
with DB('taobao', 'mysql') as f:
content = f.execute('select * from goods_brands')
t = f.fetchall()
print(t)