最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python 單例模式的幾種實(shí)現(xiàn)方式

 更新時(shí)間:2026年05月01日 10:45:41   作者:huzhongqiang  
本文分享Python單例模式四種實(shí)現(xiàn)方式(裝飾器、new、函數(shù)、lru_cache),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近在整理代碼時(shí),重新審視了項(xiàng)目中用到的單例模式實(shí)現(xiàn)。發(fā)現(xiàn)自己對(duì)單例模式的理解經(jīng)歷了一個(gè)有趣的循環(huán):從懵懂使用,到追求各種"巧妙"實(shí)現(xiàn),再到回歸樸素。

今天想分享幾種 Python 實(shí)現(xiàn)單例模式的方式,并談?wù)勎叶嗄昃幊痰囊粋€(gè)感悟:樸素的就是最好的。

一、單例模式簡介

單例模式(Singleton Pattern)是一種設(shè)計(jì)模式,確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)。

?? 適用場景

場景說明
數(shù)據(jù)庫連接全局共享一個(gè)連接池
日志記錄器避免重復(fù)打開文件
配置管理器全局只讀一份配置
緩存實(shí)例全局共享緩存

二、四種實(shí)現(xiàn)方式

方式一:類裝飾器

def singleton(cls):
    """單例裝飾器:閉包保存唯一實(shí)例"""
    _instance = None

    def wrapper(*args, **kwargs):
        nonlocal _instance
        if _instance is None:
            _instance = cls(*args, **kwargs)
        return _instance

    return wrapper


@singleton
class DBConnect:
    def __init__(self, host):
        self.host = host
        print("數(shù)據(jù)庫連接初始化")


# 使用
obj1 = DBConnect("127.0.0.1")
obj2 = DBConnect("192.168.1.1")  # 不會(huì)重新初始化

print(obj1 is obj2)  # True
print(obj1.host)     # 127.0.0.1

特點(diǎn):裝飾器語法優(yōu)雅,使用時(shí)一目了然。

方式二:__new__方法

class MySingleton:
    """單例類:通過 __new__ 控制實(shí)例創(chuàng)建"""
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance


# 使用
obj1 = MySingleton()
obj2 = MySingleton()
print(obj1 is obj2)  # True

特點(diǎn):最直接的方式,但 _instance 作為類變量暴露在外。我之前的博文 Playwright理解與封裝就是使用這種方式,感覺不太好,準(zhǔn)備重構(gòu)一下,那個(gè)類根本不需要單例模式,如果使用者覺得有必要,可以顯式自行單例化即可。

方式三:函數(shù)

from typing import Type, TypeVar

T = TypeVar('T')

def singleton(cls: Type[T], *args, **kwargs) -> T:
    """單例工廠函數(shù)"""
    if not hasattr(cls, '_instance'):
        cls._instance = cls(*args, **kwargs)
    return cls._instance


# 使用
class TargetClass:
    def __init__(self, config):
        self.config = config

obj = singleton(TargetClass, config="value")

特點(diǎn):需要顯式調(diào)用 singleton(),語義明確但稍顯繁瑣。

方式四:functools.lru_cache

from functools import lru_cache

@lru_cache(maxsize=1)
def get_instance():
    return MyClass(arg1="value")


# 使用
obj1 = get_instance()
obj2 = get_instance()
print(obj1 is obj2)  # True

特點(diǎn):Python 內(nèi)置,簡單直接,還能享受緩存的好處。

三、優(yōu)缺點(diǎn)對(duì)比

實(shí)現(xiàn)方式優(yōu)點(diǎn)缺點(diǎn)推薦指數(shù)
類裝飾器語法優(yōu)雅、語義清晰、易于理解對(duì)于非必要實(shí)現(xiàn)單例的類,對(duì)使用者會(huì)造成困擾????
new 方法最直觀、最簡單實(shí)例變量暴露、可復(fù)用性不好??
單例函數(shù)顯式調(diào)用、可控性強(qiáng),使用者清楚知道正在做什么每次都要調(diào)用、不夠直觀???
lru_cache內(nèi)置、無需額外代碼語義上不是單例、更像緩存,但是勝在簡單????

四、我的建議

?? 優(yōu)先使用顯式單例

相比把類變成單例,顯式獲取單例的寫法更加清晰:

# ? 推薦:顯式獲取單例
_db = None
def get_db():
    global _db
    if _db is None:
        _db = Database()
    return _db

# 或者更簡潔地用 lru_cache
@lru_cache
def get_db():
    return Database()
# ? 不推薦:把類變成單例,除非很確定此類必須是單例類,不會(huì)造成使用者誤解
@singleton
class Database:
    ...

為什么?

  1. 透明性:使用者能清楚看到這個(gè)類是全局共享的
  2. 可控性:可以靈活控制何時(shí)創(chuàng)建、如何創(chuàng)建
  3. 易測試:mock 和替換更容易
  4. 少歧義:不會(huì)讓使用者誤以為每次 new 都是新實(shí)例

五、多年編程感悟

樸素的就是最好的。所有當(dāng)時(shí)自鳴得意的所謂編程技巧,最后都會(huì)被證明要用更多的代價(jià)來理解和維護(hù)它。

?? 幾個(gè)教訓(xùn)

當(dāng)年覺得"巧妙"后來發(fā)現(xiàn)的問題
復(fù)雜的繼承鏈調(diào)試時(shí)一頭霧水
動(dòng)態(tài)修改類屬性難以追蹤狀態(tài)變化
魔法裝飾器新人看不懂
元編程炫技給自己挖坑

?? 回歸樸素

# 曾經(jīng)的我:要用單例模式!
@singleton
class ConfigManager:
    ...

# 現(xiàn)在的我:簡單就好
@lru_cache
def get_db():
    return Database()

簡單、直白、不需要解釋。這才是好的代碼。

六、總結(jié)

?? 要點(diǎn)回顧

  1. 裝飾器方式是最推薦的類單例實(shí)現(xiàn)(針對(duì)必須實(shí)現(xiàn)單例的類)
  2. 顯式獲取單例比把類變成單例更好
  3. lru_cache 是最簡單的單例緩存方案
  4. 樸素思維:能用簡單方式解決的問題,不要過度設(shè)計(jì)

到此這篇關(guān)于Python 單例模式的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Python 單例模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

拉萨市| 香港 | 原阳县| 鄂托克旗| 鹤庆县| 蓝田县| 浙江省| 荔波县| 高碑店市| 晋中市| 义乌市| 鄯善县| 汉寿县| 保亭| 新安县| 错那县| 南丹县| 泽库县| 濮阳县| 娱乐| 滕州市| 武陟县| 毕节市| 巴中市| 奉化市| 宽甸| 澄江县| 韶关市| 左云县| 宕昌县| 蕲春县| 武功县| 类乌齐县| 延长县| 龙川县| 兴国县| 阿合奇县| 崇礼县| 恩平市| 彰武县| 黑水县|