单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

在 Python 中,我们可以用多种方法来实现单例模式:

  • 使用模块
  • 使用__new__使
  • 用装饰器(decorator)
  • 使用元类(metaclass)

使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

class My_Singleton(object):def foo(self):pass
my_singleton = My_Singleton()

将上面的代码保存在文件mysingleton.py中,然后这样使用:

from mysingleton import my_singleton
my_singleton.foo()

使用__new__

为了使类只能出现一个实例,我们可以使用__new__来控制实例的创建过程,代码如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Singleton(object):_instance = Nonedef _new_(cls,*args,**kw):if not cls._instance:cls._instance = super(Singleton,cls)._new_(cls,*args,**kw)return cls._instance
class MyClass(Singleton):a =1

在上面的代码中,我们将类的实例和一个类变量_instance关联起来,如果cls._instance为 None 则创建实例,否则直接返回cls._instance

执行情况如下:

>>> one = MyClass()
>>> two = MyClass()
>>> one == two
True
>>> one is two
True
>>> id(one),id(two)
(4303862608,4303862608)

使用装饰器

我们知道,装饰器(decorator)可以动态地修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例,代码如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
from functools import wraps
def singleton(cls):instances = {}@wraps(cls)def getinstance(*args,**kw):if cls not in instances:instances[cls] =cls(*args,**kw)return instances[cls]return getinstance
@singleton
class MyClass(object):a = 1

在上面,我们定义了一个装饰器singleton,它返回了一个内部函数getinstance,该函数会判断某个类是否在字典instances中,如果不存在,则会将cls作为 key,cls(*args, **kw)作为 value 存到instances中,否则,直接返回instances[cls]

使用 metaclass

元类(metaclass)可以控制类的创建过程,它主要做三件事:

拦截类的创建修改类的定义返回修改后的类

使用元类实现单例模式的代码如下:

class Singleton(type):_instances = {}def _call_(cls, *args,**kwargs):if cls not in cls._instances:cls._instances[cls] =_super(Singleton,cls)._call_(*args,**kwargs)return cls._instances[cls]
#Python2
class MyClass(object):_metaclass_ = Singleton
#Python3
#ciass MyClass(metaclass=Singleton):
#   pass

小结:
Python 的模块是天然的单例模式,这在大部分情况下应该是够用的,当然,我们也可以使用装饰器、元类等方法

Python单例模式的四种创建方式实例解析相关推荐

  1. python创建单例模式_Python单例模式的四种创建方式实例解析

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  2. python 单例模式的四种创建方式

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. 单例模式的四种实现方式(饿汉模式、懒汉模式、静态内部类、枚举类)

    首先,设计模式是我们程序员在软件开发过程中面临的一般问题的解决方案,通过学习设计模式可以使我们在编程时更加有条理性,同时培养我们写代码的思维能力,从而提高我们的工作效率.接下来就跟着博主的脚步往下走吧 ...

  4. Java线程池的四种创建方式

    Java线程池的四种创建方式 Java使用Thread类来表示线程,所有的线程都是Thread类或者是他的子类.Java有四种方式来创建线程. (1)继承Thread类创建线程 (2)实现Runnab ...

  5. 【无标题】单例模式的两种创建方式:饿汉式和懒汉式

    这里写自定义目录标题 单例模式的两种创建方式:饿汉式和懒汉式 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂 ...

  6. 线程池概念、线程池作用、线程池的四种创建方式

    线程池 1.1.什么是线程池? 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常完全取决于可用内存数量和应用程 ...

  7. python 单例模式的四种实现方法

    DAY 13. 单例设计 13.1 什么是单例设计 一个类每次实例化返回的都是同一个对象,这种设计模式叫做单例设计,这个类叫做单例类 13.2 实现单例设计的方法 13.2.1 重写__new__() ...

  8. Siege压力测试工具的安装及使用+python flask的四种wsgi方式对比

    文章目录 一.前言: 如果要支持https 二.安装使用: 文件备份: 1.mac安装: 2.linux 安装:[centos 服务器] 通用Linux安装: 3.window安装: 4.测试百度: ...

  9. Java基础进阶多线程-四种创建方式

    文章目录 1.分析以下程序,有几个线程,除垃圾回收线程之外.有几个线程? 示例代码01: 2.线程创建的第一种方式:(继承Thread类) 示例代码02: 运行结果: 3.线程创建的第二种方式:(Ru ...

最新文章

  1. Python经典面试题100道(附PDF下载地址)
  2. MicroPython支持的开发板:高性能、低成本创客首选
  3. 在Android源码树中添加userspace I2C读写工具(i2c-util)
  4. print python 如何加锁_Python 进阶(一):多线程
  5. Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析)——直接看例子就明白了!!!...
  6. mysql 中如何删除重复的数据_mysql如何快速删除重复的数据
  7. 31、JAVA_WEB开发基础之servlet(2)
  8. java数据结构期末复习_java数据结构复习02
  9. 极客猿网址导航源码V3.0开源版
  10. Kali Linux 秘籍 第三章 高级测试环境
  11. [转载] python中pprint模块详解——print()和pprint()两者的区别
  12. 申请以及集成 Stripe 的 Alipay 支付方案
  13. 深入理解java:线程本地变量 java.lang.ThreadLocal类
  14. oracle授权怎么收费,Oracle数据库如何授权收费(Database Licensing)
  15. Pycahrm pip instell parsel时出现错误 error: Unable to find vcvarsall.bat解决过程
  16. python利用opencv去除图片logo_用python+OpenCV去除图片水印
  17. ⭐App爬虫之路⭐:海量食谱数据爬取持久化!!!
  18. 趋势:TypeScript - 一种思维方式
  19. 百度数据可视化Sugar BI 数据自动补全
  20. 视频教程-C++QT5跨平台界面编程原理和实战大全-C/C++

热门文章

  1. IBM向客户发放了一批“染毒”的U盘,现紧急建议物理销毁
  2. Thread Safety in the Standard C++ Library
  3. 10个相似图片搜索以图找图的网站
  4. 终于要考网络架构师了
  5. 分析模式 - 度量与测绘
  6. linux格式化大于2t硬盘分区,linux下大于2tb硬盘格式化及挂载,linux下大于2t的分区方法,linux gpt分区表 管理 自动挂载分区...
  7. 浅谈ATP检查中的“确认可用部分数量”(一)
  8. 农保和社保的区别有哪些
  9. SAP 财务模块 FI-TV 差旅管理
  10. see的口语高频用法