python实现单例模式
单例模式
说白了确保一个类不管实例化了多少次,都只有一个实例存在。
在python中,可以用类中的魔术方法__new___
来实现单例模式。
class Myclass:
_flag = None
def __new__(cls, *args, **kwargs):
if cls._flag is not None:
return cls._flag
cls._flag = super().__new__(cls)
return cls._flag
def __init__(self, name, age):
self.name = name
self.age = age
def get_info(self):
print(f"Name: {self.name}, Age: {self.age}")
c1 = Myclass('A', 20)
c2 = Myclass('B', 22)
c1.get_info() # Name: B, Age: 22
c2.get_info() # Name: B, Age: 22
魔术方法__new___
返回的是一个实例对象,会在__init___
初始化之前执行。
上面代码中,定义了一个类变量_flag
来标记类是否被实例化过,并保存第一次实例化。
如果_flag
不为None
就直接返回第一次实例化的对象,后面实例化了c1
,c2
两个对象,说白了都指向了同一个实例化的内存地址。这样就保证一个类只能有一个实例存在。
有些需求可能只要第一次实例化的属性,不是用最新的实例化对象的属性。因为__new__
方法只保证返回一个实例化对象,__init__
初始化方法在每次实例化之后都会执行,所以在实例化c2
后,类中的属性又被重新赋值了一遍。
要解决这个问题还需要加一个标记来判断示例是否被初始化过。
class Myclass:
_flag = None
_initialized = False # 初始化标记
def __new__(cls, *args, **kwargs):
if cls._flag is not None:
return cls._flag
cls._flag = super().__new__(cls)
return cls._flag
def __init__(self, name, age):
if not Myclass._initialized: # 检查是否已初始化
self.name = name
self.age = age
Myclass._initialized = True # 实例化过了
def get_info(self):
print(f"Name: {self.name}, Age: {self.age}")
c1 = Myclass('A', 20)
c2 = Myclass('B', 22)
c1.get_info() # Name: A, Age: 20
c2.get_info() # Name: A, Age: 20
上面的代码添加一个新的标记来跟踪类是否被初始化过了,只有没有实例化过才会进行初始化,这样就保证了一些属性是第一次初始化时的值。
如果文章对你有帮助!可点击按钮打赏哦 ~
发表评论
共 0 条评论
暂无评论