定义
- 确保一个类只有一个实例,并且提供一个访问它的全局方法。
单例模式的模型抽象
代码框架
方法 1:重写 __new__
和 __init__
方法
class Singleton(object):
"""单例实现方式一"""
__instance = None
__isFirstInit = False
def __new__(cls, name):
if not cls.__instance:
Singleton.__instance = super().__new__(cls)
return cls.__instance
def __init__(self, name):
if not self.__isFirstInit:
self.__name = name
Singleton.__isFirstInit = True
def getName(self):
return self.__name
# Test
tony = Singleton("Tony")
karry = Singleton("Karry")
print(tony.getName(), karry.getName())
print("id(tony):", id(tony), "id(karry):", id(karry))
print("tony == karry:", tony == karry)
运行结果
Tony Tony
id(tony): 2104575630800 id(karry): 2104575630800
tony == karry: True
调用过程:__new__
(类方法)创建对象,再调用 __init__
(对象方法)
在 Java 和 C++ 这种静态语言中,实现单例模式的一个最简单的方法就是:将构造函数声明成
private
类型的,再定义一个getInstance()
的静态方法返回一个对象,并确保 getInstance() 每次返回同一个对象即可。
方法 2:自定义 metaclass 的方法
class Singleton(type):
"""单例实现方式二"""
def __init__(cls, what, bases=None, dict=None):
super().__init__(what, bases, dict)
cls._instance = None # 初始化全局变量cls._instance为None
def __call__(cls, *args, **kwargs):
# 控制对象的创建过程,如果cls._instance为None则创建,否则直接返回
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance
class CustomClass(metaclass=Singleton):
"""用户自定义的类"""
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
tony = CustomClass("Tony")
karry = CustomClass("Karry")
print(tony.getName(), karry.getName())
print("id(tony):", id(tony), "id(karry):", id(karry))
print("tony == karry:", tony == karry)
运行结果
Tony Tony
id(tony): 2105945653456 id(karry): 2105945653456
tony == karry: True
metaclass 的简要理解(具体参考书籍附录 C):
方法 3:装饰器方法
def singletonDecorator(cls):
"""定义一个单例装饰器"""
instance = {}
def wrapperSingleton(*args, **kwargs):
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return wrapperSingleton
@singletonDecorator
class Singleton:
"""使用单例装饰器修饰一个类"""
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
tony = Singleton("Tony")
karry = Singleton("Karry")
print(tony.getName(), karry.getName())
print("id(tony):", id(tony), "id(karry):", id(karry))
print("tony == karry:", tony == karry)
运行结果
Tony Tony
id(tony): 2439916265040 id(karry): 2439916265040
tony == karry: True
基于框架的实现
def singletonDecorator(cls):
"""定义一个单例装饰器"""
instance = {}
def wrapperSingleton(*args, **kwargs):
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return wrapperSingleton
@singletonDecorator
class MyBeautifulGril(object):
"""我的漂亮女神"""
def __init__(self, name):
self.__name = name
if self.__name == name:
print("遇见" + name + ",我一见钟情!")
else:
print("遇见" + name + ",我置若罔闻!")
def showMyHeart(self):
print(self.__name + "就我心中的唯一!")
def TestLove():
jenny = MyBeautifulGril("Jenny")
jenny.showMyHeart()
kimi = MyBeautifulGril("Kimi")
kimi.showMyHeart()
print("id(jenny):", id(jenny), " id(kimi):", id(kimi))
TestLove()
运行结果
遇见Jenny,我一见钟情!
Jenny就我心中的唯一!
Jenny就我心中的唯一!
id(jenny): 1678521765456 id(kimi): 1678521765456
应用场景
- 你希望这个类只有一个且只能有一个实例。
- 项目中的一些全局管理类(Manager)可以用单例模式来实现。