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单例模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python人工智能实战之以图搜图的实现

    Python人工智能实战之以图搜图的实现

    这篇文章主要为大家详细介绍了如何基于vgg网络和Keras深度学习框架实现以图搜图功能。文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2022-05-05
  • 详解java调用python的几种用法(看这篇就够了)

    详解java调用python的几种用法(看这篇就够了)

    这篇文章主要介绍了详解java调用python的几种用法(看这篇就够了),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • numpy中loadtxt 的用法详解

    numpy中loadtxt 的用法详解

    这篇文章主要介绍了numpy中loadtxt 的用法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • python求素数示例分享

    python求素数示例分享

    这篇文章主要介绍了python求素数示例,打印出素数列表,需要的朋友可以参考下
    2014-02-02
  • PyTorch实现重写/改写Dataset并载入Dataloader

    PyTorch实现重写/改写Dataset并载入Dataloader

    这篇文章主要介绍了PyTorch实现重写/改写Dataset并载入Dataloader,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • python运行cmd命令行的3种方法总结

    python运行cmd命令行的3种方法总结

    虽然python在调用cmd命令方面使用的比较少,不过还是要用的,下面这篇文章主要给大家介绍了关于python运行cmd命令行的3种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Django用户认证系统 User对象解析

    Django用户认证系统 User对象解析

    这篇文章主要介绍了Django用户认证系统 User对象解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Python 获取div标签中的文字实例

    Python 获取div标签中的文字实例

    今天小编就为大家分享一篇Python 获取div标签中的文字实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python给文件夹加解密的实现

    Python给文件夹加解密的实现

    数据泄露已经成为一个严重的问题,为了保护用户和公司的隐私,给文件夹加密已经成为一个必要的步骤,本文主要介绍了Python给文件夹加解密的实现,感兴趣的可以了解一下
    2023-11-11
  • python 字符串split的用法分享

    python 字符串split的用法分享

    python 字符串的split方法是用的频率还是比较多的。比如我们需要存储一个很长的数据,并且按照有结构的方法存储,方便以后取数据进行处理。当然可以用json的形式。但是也可以把数据存储到一个字段里面,然后有某种标示符来分割
    2013-03-03

最新评论