Python实现设计模式之单例模式详解

 更新时间:2023年09月22日 08:43:52   作者:XWenXiang  
这篇文章主要介绍了Python实现设计模式之单例模式详解,设计模式是指软件设计问题的推荐方案,设计模式一般是描述如何组织代码和使用最佳实践来解决常见的设计问题,需谨记一点:设计模式是高层次的方案,并不关注具体的实现细节,比如算法和数据结构,需要的朋友可以参考下

设计模式简介

设计模式是指软件设计问题的推荐方案。设计模式一般是描述如何组织代码和使用最佳实践来解决常见的设计问题。需谨记一点:设计模式是高层次的方案,并不关注具体的实现细节,比如算法和数据结构。

设计模式共分为三大类,细分为23种设计模式。

1. 创建型模式

2. 结构型模式

3. 行为型模式

单例

单例模式属于创建型模式,是一个比较常用的一个设计模式,单例模式主要作用是让一个类只有一个实例对象,因为在某些时候创建多个实例对象会浪费内存,所以目的就是为了节省内存资源。

既然是约束只能生成一个实例对象,那么就应该在实例化的过程进行修改,编写单例的方法有很多种

使用元类 __call__

代码示例(基于元类) 

class Single(type):  # 定义继承元类type的类
		    def __call__(self, *args, **kwargs):  # 重写 __call__ 在类加括号调用时执行
		        if not hasattr(self, 'new_obj'):  # 判断类名有没有指定属性
		        	# 若没有,则添加指定属性,属性值是元类__call__的返回值也就是类名
		            self.new_obj = super().__call__(*args, **kwargs)  
		        return self.new_obj
		class MyClass(metaclass=Single):
		    def __init__(self, name):
		        self.name = name
		obj1 = MyClass('X')
		obj2 = MyClass('W')
		print(obj1 is obj2)
		print(obj1)
		print(obj2)

打印结果

        True
        <__main__.MyClass object at 0x000001F9B382E350>
        <__main__.MyClass object at 0x000001F9B382E350>

此时创建多个实例并不会执行,只指向一个实例。

使用 __new__ 方法 

__new__ 方法在类的实例化过程最先执行,默认执行 object 的 __new__ 方法,返回一个实例化对象,然后再调用 __init__ 方法,对这个对象进行初始化

class MyCls(object):  # 定义继承元类type的类
		    def __new__(cls, *args, **kwargs):  # 重写 __new__ 方法
		        if not hasattr(cls, 'new_obj'):  # 如果类名没有指定属性
		        	# 给类名添加属性,属性值是 object 的__new__方法返回值
		            cls.new_obj = super().__new__(cls, *args, **kwargs)
		        return cls.new_obj  # 将属性值返回
		obj = MyCls()
		obj1 = MyCls()
		print(obj is obj1)
		print(obj)
		print(obj1)

打印结果

        True
        <__main__.MyCls object at 0x0000024968276500>
        <__main__.MyCls object at 0x0000024968276500>

第一次实例化的时候,由于判断其没有指定属性,执行添加属性语句,属性值是 object 的 __new__ 方法的返回值,最后返回指定属性的值,也就是类名,而第二次实例化的时候由于已经添加了属性,所以直接返回object 的 __new__ 方法,所以其实他们一直是同一个属性值。

使用 @classmethod

@classmethod 会自动将类名传入到 cls 变量中

class MyCls(object):
		    _instance = None  # 定义一个变量用于判断
		    def __init__(self):
		        pass
		    @classmethod  # 定义一个类方法
		    def singleton(cls):
		        if not cls._instance:  # 如果类中的指定属性为None
		            cls._instance = MyCls()  # 设置属性,属性值为实例对象
		        return cls._instance  # 将指定属性返回
		obj1 = MyCls.singleton()  # 只能用类方法来获取实例对象
		obj2 = MyCls.singleton()  # 只能用类方法来获取实例对象
		print(obj1)
		print(obj2)

打印结果

        <__main__.MyCls object at 0x000002396ABB5D20>
        <__main__.MyCls object at 0x000002396ABB5D20>

这个有些不同,只能用类方法来获取实例对象。第一次调用类方法创建实例对象的时候在类方法中得到了一个实例对象返回值,而在第二次调用类方法创建对象的时候已经有了指定属性,不满足类方法中的判断条,所以获得的还是第一次实例化得到的对象。

使用装饰器

使用装饰器实现实例化并返回出来

def outer(cls):  # 定义装饰器
		    _instance = None  # 定义变量用于判断
		    def inner(*args, **kwargs):
		        nonlocal _instance  # 声明变量
		        if not _instance:  # 如果变量是 None
		            _instance = cls(*args, **kwargs)  # 设置属性,属性值为实例对象
		        return _instance  
		    return inner
		@outer  # 调用装饰器,将类名传入到cls,也就是此时相当于 outer(MyCls)
		class MyCls:
		    pass
		obj = MyCls()
		obj1 = MyCls()
		print(obj)
		print(obj1)

打印结果

        <__main__.MyCls object at 0x00000165FDE05D20>
        <__main__.MyCls object at 0x00000165FDE05D20>

使用模块

模块的方式就是在一个py文件中定义一个类,并实例化一个对象,之后在其他文件导入这一对象

到此这篇关于Python实现设计模式之单例模式详解的文章就介绍到这了,更多相关Python单例模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Matplotlib控制坐标轴刻度间距与标签实例代码

    Matplotlib控制坐标轴刻度间距与标签实例代码

    在matplotlib中,记号是图形两个轴上的小标记,到目前为止,我们让matplotlib处理轴图例上记号的位置,下面这篇文章主要给大家介绍了关于Matplotlib控制坐标轴刻度间距与标签的相关资料,需要的朋友可以参考下
    2021-10-10
  • Python列表生成式和字典生成式实例

    Python列表生成式和字典生成式实例

    这篇文章主要介绍了Python列表生成式和字典生成式实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • python定时器使用示例分享

    python定时器使用示例分享

    这篇文章主要介绍了python定时器使用示例,需要的朋友可以参考下
    2014-02-02
  • pycharm中import导入包呈现灰色的问题及解决

    pycharm中import导入包呈现灰色的问题及解决

    这篇文章主要介绍了pycharm中import导入包呈现灰色的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 详解Python中os.path与pathlib的用法和性能对比

    详解Python中os.path与pathlib的用法和性能对比

    pathlib 模块是在Python3.4版本中首次被引入到标准库中的,这篇文章主要来和大家介绍一下Python中os.path与pathlib再用法和性能上的区别,感兴趣的可以了解下
    2024-03-03
  • Python利用matplotlib.pyplot绘图时如何设置坐标轴刻度

    Python利用matplotlib.pyplot绘图时如何设置坐标轴刻度

    Matplotlib是Python提供的一个二维绘图库,所有类型的平面图,包括直方图、散点图、折线图、点图、热图以及其他各种类型,都能由Python制作出来。本文主要介绍了关于Python利用matplotlib.pyplot绘图时如何设置坐标轴刻度的相关资料,需要的朋友可以参考下。
    2018-04-04
  • python切割图片的示例

    python切割图片的示例

    这篇文章主要介绍了利用python切割图片的示例,帮助大家更好的利用python处理图片,感兴趣的朋友可以了解下
    2020-11-11
  • Python GUI之tkinter窗口视窗教程大集合(推荐)

    Python GUI之tkinter窗口视窗教程大集合(推荐)

    这篇文章主要介绍了Python GUI之tkinter窗口视窗教程大集合,看这一篇教程足了,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 利用pandas向一个csv文件追加写入数据的实现示例

    利用pandas向一个csv文件追加写入数据的实现示例

    这篇文章主要介绍了利用pandas向一个csv文件追加写入数据的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • Python利用docx模块实现快速操作word文件

    Python利用docx模块实现快速操作word文件

    这篇文章主要为大家详细介绍了Python如何利用docx模块实现快速操作word文件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-09-09

最新评论