常见的在Python中实现单例模式的三种方法


Posted in Python onApril 08, 2015

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。在Python中,单例模式有以下几种实现方式。

方法一、实现__new__方法,然后将类的一个实例绑定到类变量_instance上;如果cls._instance为None,则说明该类还没有被实例化过,new一个该类的实例,并返回;如果cls._instance不为None,直接返回_instance,代码如下:

class Singleton(object):
 
  def __new__(cls, *args, **kwargs):
    if not hasattr(cls, '_instance'):
      orig = super(Singleton, cls)
      cls._instance = orig.__new__(cls, *args, **kwargs)
    return cls._instance
 
class MyClass(Singleton):
  a = 1
 
one = MyClass()
two = MyClass()
 
#one和two完全相同,可以用id(), ==, is检测
print id(one)  # 29097904
print id(two)  # 29097904
print one == two  # True
print one is two  # True

方法二、本质上是方法一的升级版,使用__metaclass__(元类)的高级python用法,具体代码如下:

class Singleton2(type):
 
  def __init__(cls, name, bases, dict):
    super(Singleton2, cls).__init__(name, bases, dict)
    cls._instance = None
 
  def __call__(cls, *args, **kwargs):
    if cls._instance is None:
      cls._instance = super(Singleton2, cls).__call__(*args, **kwargs)
    return cls._instance
 
class MyClass2(object):
  __metaclass__ = Singleton2
  a = 1
 
one = MyClass2()
two = MyClass2()
 
print id(one)  # 31495472
print id(two)  # 31495472
print one == two  # True
print one is two  # True

方法三、使用Python的装饰器(decorator)实现单例模式,这是一种更Pythonic的方法;单利类本身的代码不是单例的,通装饰器使其单例化,代码如下:

def singleton(cls, *args, **kwargs):
  instances = {}
  def _singleton():
    if cls not in instances:
      instances[cls] = cls(*args, **kwargs)
    return instances[cls]
  return _singleton
 
@singleton
class MyClass3(object):
  a = 1
 
one = MyClass3()
two = MyClass3()
 
print id(one)  # 29660784
print id(two)  # 29660784
print one == two  # True
print one is two  # True
Python 相关文章推荐
Django中实现一个高性能计数器(Counter)实例
Jul 09 Python
python中的__slots__使用示例
Feb 26 Python
详解Python3.1版本带来的核心变化
Apr 07 Python
Python插件virtualenv搭建虚拟环境
Nov 20 Python
Python实现判断给定列表是否有重复元素的方法
Apr 11 Python
Pycharm取消py脚本中SQL识别的方法
Nov 29 Python
python3下载抖音视频的完整代码
Jun 05 Python
PyQt5 QTable插入图片并动态更新的实例
Jun 18 Python
Django数据结果集序列化并展示实现过程
Apr 22 Python
Python‘==‘ 及 ‘is‘相关原理解析
Sep 05 Python
关于Python字符编码与二进制不得不说的一些事
Oct 04 Python
python神经网络 使用Keras构建RNN训练
May 04 Python
分析Python的Django框架的运行方式及处理流程
Apr 08 #Python
给Python的Django框架下搭建的BLOG添加RSS功能的教程
Apr 08 #Python
在Python中使用NLTK库实现对词干的提取的教程
Apr 08 #Python
使用Python操作Elasticsearch数据索引的教程
Apr 08 #Python
用Python实现协同过滤的教程
Apr 08 #Python
在Python中调用ggplot的三种方法
Apr 08 #Python
Python字符串和文件操作常用函数分析
Apr 08 #Python
You might like
php 采集书并合成txt格式的实现代码
2009/03/01 PHP
解析php时间戳与日期的转换
2013/06/06 PHP
浅谈PHP拦截器之__set()与__get()的理解与使用方法
2016/10/18 PHP
JS 字符串连接[性能比较]
2009/05/10 Javascript
jquery蒙版控件实现代码
2010/12/08 Javascript
解析DHTML,JavaScript,DOM,BOM以及WEB标准的描述
2013/06/19 Javascript
JS解决ie6下png透明的方法实例
2013/08/02 Javascript
登陆成功后自动计算秒数执行跳转
2014/01/23 Javascript
JS控制表单提交的方法
2015/07/09 Javascript
JQ实现新浪游戏首页幻灯片
2015/07/29 Javascript
angularjs创建弹出框实现拖动效果
2020/08/25 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
完美解决IE9浏览器出现的对象未定义问题
2016/09/29 Javascript
canvas仿iwatch时钟效果
2017/03/06 Javascript
JavaScript实现开关等效果
2017/09/08 Javascript
Angular中支持SCSS的方法
2017/11/18 Javascript
微信小程序实现bindtap等事件传参
2019/04/08 Javascript
详解新手使用vue-router传参时注意事项
2019/06/06 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
微信小程序返回上一页传参并刷新过程解析
2019/12/13 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
2020/08/14 Javascript
vue 使用原生组件上传图片的实例
2020/09/08 Javascript
原生js生成图片验证码
2020/10/11 Javascript
Python黑魔法Descriptor描述符的实例解析
2016/06/02 Python
python中字符串的操作方法大全
2018/06/03 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
对python以16进制打印字节数组的方法详解
2019/01/24 Python
对Python协程之异步同步的区别详解
2019/02/19 Python
详解用python写网络爬虫-爬取新浪微博评论
2019/05/10 Python
分享一个pycharm专业版安装的永久使用方法
2019/09/24 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
家长会主持词
2014/03/26 职场文书
国庆节促销广告语2014
2014/09/19 职场文书
2014年自愿离婚协议书
2014/10/10 职场文书
小学生暑假安全保证书
2015/07/13 职场文书