【一】單例模式概念
- 單例模式是一種設(shè)計(jì)模式,其核心思想是確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn)。
- 單例模式通常用于管理共享的資源,例如配置信息、數(shù)據(jù)庫(kù)連接、線程池等。
- 關(guān)鍵點(diǎn)在于如何判斷這個(gè)類是否已經(jīng)實(shí)例化
- 通過(guò)模塊導(dǎo)入:借助模塊的底層導(dǎo)入原理
- 通過(guò)元類實(shí)現(xiàn):元類的魔法方法
__call__
會(huì)在實(shí)例化之前執(zhí)行,可以進(jìn)行判斷 - 通過(guò)裝飾器實(shí)現(xiàn):裝飾器也會(huì)在實(shí)例化之前操作,可以盡心判斷
【二】單例模式實(shí)現(xiàn)方法
【1】通過(guò)模塊導(dǎo)入
- 這是最簡(jiǎn)單并且最好理解的方法,建議就用這個(gè)
# module.py文件內(nèi)容
class FuncTools(object):
pass
func_tools = FuncTools()
# 需要導(dǎo)入這個(gè)功能對(duì)象的文件
from module import func_tools
functools......
- 模塊只會(huì)導(dǎo)入一次,第二次導(dǎo)入時(shí)在內(nèi)存中找到了這個(gè)實(shí)例對(duì)象,所以就不會(huì)再次生成一個(gè)新的實(shí)例
【2】通過(guò)元類實(shí)現(xiàn)
- 有一點(diǎn)難度
class MyMeta(type):
__have_instance = None
def __call__(cls, *args, **kwargs):
if not cls.__have_instance:
obj = super().__call__(*args, **kwargs)
cls.__have_instance = obj
return cls.__have_instance
class Student(metaclass=MyMeta):
def __init__(self, name):
self.name = name
student_one = Student("bruce")
print(student_one.name, id(student_one))
# bruce 2973012426224
student_two = Student("tom")
print(student_two.name, id(student_two))
# bruce 2973012426224
- 在生成實(shí)例(
student_one
)的時(shí)候觸發(fā)元類(MyMeta
)的__call__
方法進(jìn)行判斷沒(méi)有實(shí)例,創(chuàng)建了實(shí)例 - 在生成第二個(gè)實(shí)例(
student_two
)的時(shí)候再次觸發(fā)元類(MyMeta
)的__call__
方法進(jìn)行判斷,有了實(shí)例直接返回已經(jīng)存在,所以不會(huì)創(chuàng)建新的實(shí)例 - 為什么是用的元類(
MyMeta
)的__call__
方法呢?- 因?yàn)?code>__init__和
__new__
都是在定義類(Student
)的時(shí)候執(zhí)行的 - 僅執(zhí)行了一次,并且還是在實(shí)例(
student_one
)之前觸發(fā)的 - 所以只能用元類(
MyMeta
)的__call__
- 因?yàn)?code>__init__和
【3】通過(guò)裝飾器實(shí)現(xiàn)
- 理解難度比元類好一點(diǎn)
def singleton(cls):
cls_dict = {}
def inner(*args, **kwargs):
if cls not in cls_dict.keys():
cls_dict[cls] = cls(*args, **kwargs)
return cls_dict[cls]
return inner
@singleton
class Student(object):
def __init__(self, name):
self.name = name
student_one = Student("bruce")
print(student_one.name, id(student_one))
student_two = Student("tom")
print(student_two.name, id(student_two))
- 通過(guò)裝飾器
singleton
裝飾類(Student
) - 在生成第一個(gè)學(xué)生(
bruce
)時(shí),判斷沒(méi)有這個(gè)類沒(méi)有產(chǎn)生實(shí)例,所以創(chuàng)建了實(shí)例(student_one
) - 在生成第二個(gè)學(xué)生(
tom
)時(shí),判斷這個(gè)類已經(jīng)生成過(guò)實(shí)例,所以沒(méi)有創(chuàng)建新的,返回第一次生成的實(shí)例(student_one
)
【三】總結(jié)
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-824518.html
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-824518.html
到了這里,關(guān)于Python 面向?qū)ο笾畣卫J降奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!