Python设计模式之单例模式丨【生长吧!Python】
【摘要】 Python设计模式之单例模式
1、什么是单例模式
确保一个类只有一个实例,并且提供一个访问它的全局方法。
2、单例模式设计思想
单例模式就是保证一个类有且只有一个对象(实例)的一种机制。单例模式用来控制某些事物只允许有一个个体。
3、单例模式的模型抽象
3.1、代码框架
单例模式的实现方式有很多种,下面列出几种常见的方式。
3.1.1、重写__new__和__init__方法
1、代码
class Singleton(object):
"""单例实现方式一"""
__instance = None
__isFirstInit = False
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__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)
2、输出结果
Tony Tony
id(tony): 2448374521616 id(karry): 2448374521616
tony == karry: True
3、说明
1、在Python 3的类中,__new__负责对象的创建,而__init__负责对象的初始化;__new__是一个类方法,而__init__是一个对象方法。
2、__new__是我们通过类名进行实例化对象时自动调用的,__init__是在每一次实例化对象之后调用的,__new__方法创建一个实例之后返回这个实例的对象,并将其传递给__init__方法的self参数。
3、在上面的示例代码中,我们定义了一个静态的__instance 类变量,用来存放Singleton的对象,__new__方法每次返回同一个__instance 对象(若未初始化,则进行初始化)。因为每一次通过 s=Singleton()的方式创建对象时,都会自动调用__init__方法来初始化实例对象,因此__isFirstInit 的作用就是确保只对__instance 对象进行一次初始化。
3.1.2、自定义metaclass的方法
1、代码
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)
2、输出结果
Tony Tony
id(tony): 2172407274992 id(karry): 2172407274992
tony == karry: True
3、说明
在上面的代码中,我们定义了metaclass(Singleton)来控制对象的实例化过程。
在定义自己的类时,我们通过 class CustomClass(metaclass=Singleton)来显式地指定 metaclass 为Singleton。
3.1.3、装饰器的方法
1、代码
def singletonDecorator(cls, *args, **kwargs):
"""定义一个单例装饰器"""
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)
2、输出结果
Tony Tony
id(tony): 2975555472736 id(karry): 2975555472736
tony == karry: True
3、说明
装饰器的实质就是对传进来的参数进行补充,可以在不对原有的类做任何代码变动的前提下增加额外的功能,使用装饰器可以装饰多个类。
用装饰器的方式来实现单例模式,通用性非常高,在实际项目中用得非常多。
3.2、类图
类图非常简单,只有一个类,类中只有一个方法,getInstance()的作用就是获取该类的唯一实例。
【生长吧!Python】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/278897
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)