Python 实现单例模式

单例模式是一种软件设计模式。

在面向对象编程中,通过单例模式只能创建一个类实例,也就是一个类永远只有一个实例对象。

在工作中,为了确保某一个类只会创建出一个实例,就需要使用单例模式。

在 Python 中,实现单例的方法有很多。

一、通过装饰器的方式实现单例

def singleton_func(cls):instances = {}def _singleton(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return _singleton@singleton_func
class Phone(object):def phone_id(self):return id(self)p1 = Phone()
p2 = Phone()
print(p1.phone_id())
print(p2.phone_id())

运行结果:

44502488
44502488

通过装饰器来实现单例,直接用装饰器装饰类,实例化两遍类对象,对象的id是相等的,说明并没有两个实例对象,只是两个变量指向一个单例。如果注释掉上面的装饰器,则创建的是两个不同的实例(id不相等)。

在 Python 中,一切皆对象,所以字典中的数据也是一个个的对象。

在装饰器的内函数中,判断字典是否已经有键值对。如果没有,则添加一个类和类实例的键值对,如果有,则不添加。最后返回字典中的类实例,可以保证每次返回的都是同一个实例。

要使用这个单例装饰器,只要将其装饰到需要实现单例的类上即可。

在单例的多种实现方式中,个人最推荐这种方式,因为装饰器的使用方式即方便又优雅。我们可以将以上装饰器写在一个py文件中,所有需要使用单例的地方,都可以使用,步骤就两个,导入,装饰,如果不需要单例了,注释掉装饰器即可。

装饰器参考:https://blog.csdn.net/weixin_43790276/article/details/90728864

二、使用实例化方式实现单例

class SingletonInstance(object):def __call__(self, *args, **kwargs):return selfSingletonInstance = SingletonInstance()
s1 = SingletonInstance()
s2 = SingletonInstance()
print(id(s1))
print(id(s2))

运行结果:

51186264
51186264

在类中,先重写类的 __call__ 方法,在 __call__ 方法中返回自己。先实例化一个类的对象,后面所有需要使用这个类的地方,都调用这个实例对象。这样,每次调用的都是同一个实例,所以也能实现单例。

其实 Python 中的模块默认是单例模式的,在其他py文件中导入这个实例,然后使用,也是满足单例模式的。

三、使用类装饰器实现单例

class SingletonDecorator(object):_instance = Nonedef __init__(self, cls):self._cls = clsdef __call__(self, *args, **kwargs):if self._instance is None:self._instance = self._cls(*args, **kwargs)return self._instance@SingletonDecorator
class Phone(object):def phone_id(self):return id(self)p1 = Phone()
p2 = Phone()
print(p1.phone_id())
print(p2.phone_id())

运行结果:

47898464
47898464

使用装饰器实现单例,因为装饰器除了可以使用闭包实现,还可以使用类实现,所以也可以使用类装饰器来实现单例。

通过重写类的 __call__ 方法实现类装饰器,在 __call__ 方法中判断当前是否有类实例,没有才会创建,从而实现单例。

四、重写类的 __new__ 方法实现单例

class SingletonClass(object):_instance = Nonedef __new__(cls, *args, **kwargs):if cls._instance is None:cls._instance = super(SingletonClass, cls).__new__(cls)return cls._instance_is_init = Falsedef __init__(self):if self._is_init is False:print('-*-')self._is_init = Trues1 = SingletonClass()
s2 = SingletonClass()
print(id(s1))
print(id(s2))

运行结果:

-*-
57946912
57946912

在 Python 类中,每次实例化一个类对象时,都会自动先执行 __new__ 方法和 __init__ 方法。 __new__ 方法先在内存中为实例对象申请空间,然后 __init__ 方法初始化实例对象。

通过重写 __new__ 方法,如果这个类没有实例对象,则执行 __new__ 方法,有则返回已有的实例,这样就实现了单例。

但是,因为 __init__ 方法是在 __new__ 执行完成后自动执行的,每次实例类的对象时都会执行 __init__ 方法,所以也要对 __init__ 方法进行重写,只有第一次实例化类对象时才执行初始化操作。如果上面代码中不重写 __init__ 方法,则会执行两遍__init__ 方法。

五、通过元类实现单例

class SingletonMeta(type, object):def __init__(self, *args, **kwargs):self._instance = Nonesuper(SingletonMeta, self).__init__(*args, **kwargs)# _instance = Nonedef __call__(self, *args, **kwargs):if self._instance is None:self._instance = super(SingletonMeta, self).__call__(*args, **kwargs)return self._instanceclass Phone(object, metaclass=SingletonMeta):def phone_id(self):return id(self)p1 = Phone()
p2 = Phone()
print(p1.phone_id())
print(p2.phone_id())

运行结果:

2325532722344
2325532722344

在 Python 中,元类是创建类的类,是创建类的工厂,所有类的元类都是 type 类,所有类都是 type 类的实例对象。

元类参考:https://blog.csdn.net/weixin_43790276/article/details/90756859

如果自定义一个元类,在元类中重写 __call__ 方法,判断当前是否有实例,没有实例才创建,有则不创建。对需要实现单例的类,指定类的元类是我们自定义的元类,从而实现单例。

不过,不推荐使用这种方式。

Python 实现单例模式相关推荐

  1. Python设计模式-单例模式

    Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...

  2. python采用单例模式游戏_Python实现Singleton模式的方式详解

    前言 使用python实现设计模式中的单例模式.单例模式是一种比较常用的设计模式,其实现和使用场景判定都是相对容易的.本文将简要介绍一下python中实现单例模式的几种常见方式和原理.一方面可以加深对 ...

  3. python实现单例模式的几种方式_基于Python中单例模式的几种实现方式及优化详解...

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

  4. python实现单例模式的三种方式及相关知识解释

    python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singlet ...

  5. Python实现单例模式的几种方式

    认识单例模式 含义 单例模式是一种常用的软件设计模式,在应用这个模式时,类只会生成一个实例对象. 换句话说,单例模式确保某个类有且仅有一个实例,而且自行实例化并向整个系统提供这个实例,当我们在程序中的 ...

  6. Python 设计模式: 单例模式(singleton pattern)

    2019独角兽企业重金招聘Python工程师标准>>> 如果想在整个程序的运行过程中,某个类只有一个实例的话,可以通过单例模式来实现. 在 Python 中实现单例模式有很多种方式, ...

  7. Python创建单例模式的5种方法

    单例模式(Singleton Pattern)是一种常用的软件设计模式,是指一个类的实例从始至终只能被创建一次,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例:为了 ...

  8. python实现单例模式的三种方法

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

  9. python:单例模式--使用__new__(cls)实现

    单例模式:即一个类有且仅有一个实例. 那么通过python怎么实现一个类只能有一个实例呢. class Earth:"""假如你是神,你可以创造地球"" ...

最新文章

  1. Python 炫技操作:合并字典的七种方法
  2. 出门问问工程副总裁黄美玉入选IEEE Fellow,曾担任微软Cortana首席NLP科学家
  3. Item 13 Minimize the accessibility of classes and members
  4. MATLAB基础教程(5)——斐波那契数列
  5. K均值聚类关于初始聚类中心选取的一种改进(python程序)
  6. centos 安装 lua运行环境   非yum安装
  7. 信息收集-目录扫描(7kbscan御剑版)下载及使用
  8. 【Python】 _tkinter.TclError: bitmap xzw.ico not defined
  9. windows下Docker的下载与安装
  10. SM2椭圆曲线公钥加密算法
  11. Linux网络驱动MDIO及Phy梳理
  12. SAP Fiori 的学习路线指南
  13. java-net-php-python-jsp无锡尚客优酒店客房管理信息系统mp4计算机毕业设计程序
  14. 操作系统的主要功能是什么
  15. 轻松在线绘制进化树和增加热图注释
  16. java获取当天开始,结束时间
  17. Object的notify和notifyAll方法的区别
  18. go cobra初试
  19. 逆向工程实验Lab0
  20. lisp6 暖通cad_CAD迷你看图软件_CAD制图工具下载_免费CAD软件下载-华军纯净下载

热门文章

  1. ARP:地址解析协议
  2. 使用Hyper-V创建虚拟机
  3. Selenium代码示例
  4. 什么是 Unix 以及它为什么这么重要?
  5. IBM原厂资深专家:DB2优化器和成本模型分析
  6. android的开始时对bug的定位和处理
  7. 零基础也可现学苹果Swift语言?太傻太天真
  8. ural(Timus) 1019 Line Painting
  9. 实现 npm script 跨平台兼容
  10. ElasticSearch面试 - es 生产集群的部署架构是什么?