with 與上下文管理器

對於系統資源如文件、數據庫連接、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)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章