【一】单例模式概念
单例模式是一种设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点。 单例模式通常用于管理共享的资源,例如配置信息、数据库连接、线程池等。 关键点在于如何判断这个类是否已经实例化
通过模块导入:借助模块的底层导入原理 通过元类实现:元类的魔法方法__call__
会在实例化之前执行,可以进行判断 通过装饰器实现:装饰器也会在实例化之前操作,可以尽心判断
【二】单例模式实现方法
【1】通过模块导入
class FuncTools ( object ) :
pass
func_tools = FuncTools( )
from module import func_tools
functools. . . . . .
模块只会导入一次,第二次导入时在内存中找到了这个实例对象,所以就不会再次生成一个新的实例
【2】通过元类实现
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) )
student_two = Student( "tom" )
print ( student_two. name, id ( student_two) )
在生成实例(student_one
)的时候触发元类(MyMeta
)的__call__
方法进行判断没有实例,创建了实例 在生成第二个实例(student_two
)的时候再次触发元类(MyMeta
)的__call__
方法进行判断,有了实例直接返回已经存在,所以不会创建新的实例 为什么是用的元类(MyMeta
)的__call__
方法呢?
因为__init__
和__new__
都是在定义类(Student
)的时候执行的 仅执行了一次,并且还是在实例(student_one
)之前触发的 所以只能用元类(MyMeta
)的__call__
【3】通过装饰器实现
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) )
通过装饰器singleton
装饰类(Student
) 在生成第一个学生(bruce
)时,判断没有这个类没有产生实例,所以创建了实例(student_one
) 在生成第二个学生(tom
)时,判断这个类已经生成过实例,所以没有创建新的,返回第一次生成的实例(student_one
)
【三】总结