­

一日一技: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類就會被實例化,無法做到等到需要的時候才實例化。