一日一技:Python 下面最簡單的單例模式寫法

  • 2019 年 11 月 14 日
  • 筆記

攝影:產品經理

買單:kingname

二十幾種設計模式中,單例模式是最簡單最常用的一種。在其他語言裡面實現單例模式要寫不少程式碼,但是在 Python 裡面,有一種非常簡單的單例模式寫法。

為了演示這種簡單的寫法,我們首先創建一個文件,DBUtil.py文件,用來模擬資料庫操作類。這個文件裡面的程式碼如下:

class DBUtil:      def __init__(self):          self.conn = self.connect()        def connect(self):          print('創建資料庫連接')          return 'connect'        def write(self, data):          print(f'寫入數據:{data}')        def read(self):          print('從資料庫中讀取數據')          return 123  

現在我們創建兩個文件:a.pyb.py,用來模擬在一個工程裡面的兩個不同地方同時調用資料庫操作類並初始化的過程。

a.py內容如下:

from DBUtil import DBUtil  from b import run    data = run()  db_util = DBUtil()  db_util.write(data)  

b.py的內容如下:

from DBUtil import DBUtil    def run():      db_util = DBUtil()      data = db_util.read()      return data  

運行效果如下圖所示:

可以看到,創建資料庫連接被列印了兩次,說明DBUtil類被實例化了兩次。對應到真實的項目中,就是創建了多個到資料庫的鏈接。這樣是很浪費資源的。

當然,你可以在 a.py中初始化DBUtil,然後把這個對象作為參數傳入run函數裡面,再run函數裡面調用這個對象的read()方法。

但是在實際項目中,往往會出現很多層的調用,如果要把一個對象一層一層傳下去,不僅讓參數列表顯得雜亂,還容易漏掉或者搞錯順序。

所以,使用單例模式就能避免通過參數傳遞對象,但又不會創建多個資料庫連接。

網上關於單例模式的程式碼有很多。本文將會介紹最簡單的一種,利用 Python 的import機制。在 Python 裡面,一個模組只會被導入1次,如果多次使用import xxx導入同一個模組,後面的導入語句會被自動忽略。利用這個機制,我們就能很容易實現單例模式。

修改DBUtil.py,在它的最下面加上一行程式碼:

class DBUtil:      def __init__(self):          self.conn = self.connect()        def connect(self):          print('創建資料庫連接')          return 'connect'        def write(self, data):          print(f'寫入數據:{data}')        def read(self):          print('從資料庫中讀取數據')          return 123    db_util = DBUtil()  

修改a.py:

from DBUtil import db_util  from b import run    data = run()  db_util.write(data)  

修改b.py:

from DBUtil import db_util    def run():      data = db_util.read()      return data  

運行以後的效果如下圖所示:

可以看到,創建資料庫連接只列印了1次,說明單例模式成功。

這種單例模式非常簡單,但是有一個弊端,就是無法實現懶載入。程式剛剛開始運行,DBUtil類就會被實例化,無法做到等到需要的時候才實例化。