常见的在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 相关文章推荐
python局域网ip扫描示例分享
Apr 03 Python
Python标准库之sqlite3使用实例
Nov 25 Python
用生成器来改写直接返回列表的函数方法
May 25 Python
Python中input与raw_input 之间的比较
Aug 20 Python
Python使用reportlab模块生成PDF格式的文档
Mar 11 Python
python如何删除文件中重复的字段
Jul 16 Python
用Python批量把文件复制到另一个文件夹的实现方法
Aug 16 Python
Django之form组件自动校验数据实现
Jan 14 Python
详解Python中namedtuple的使用
Apr 27 Python
使用OpenCV校准鱼眼镜头的方法
Nov 26 Python
Python selenium模拟网页点击爬虫交管12123违章数据
May 26 Python
Python turtle实现贪吃蛇游戏
Jun 18 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
一个ubbcode的函数,速度很快.
2006/10/09 PHP
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
php下删除字符串中HTML标签的函数
2008/08/27 PHP
PHP similar_text 字符串的相似性比较函数
2010/05/26 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
php图片上传类 附调用方法
2016/05/15 PHP
浅析php如何实现爬取数据原理
2018/09/27 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
科讯商业版中用到的ajax空间与分页函数
2007/09/02 Javascript
jQuery EasyUI 中文API Layout(Tabs)
2010/04/27 Javascript
c#和Javascript操作同一json对象的实现代码
2012/01/17 Javascript
js function定义函数的几种不错方法
2014/02/27 Javascript
JQuery $.each遍历JavaScript数组对象实例
2014/09/01 Javascript
jquery实现搜索框常见效果的方法
2015/01/22 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
2015/03/26 Javascript
Vue.js每天必学之数据双向绑定
2016/09/05 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
2016/10/05 Javascript
在vue-cli中组件通信的方法
2017/12/16 Javascript
vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法
2018/09/19 Javascript
详解小程序退出页面时清除定时器
2019/04/28 Javascript
vue 集成 vis-network 实现网络拓扑图的方法
2019/08/07 Javascript
微信小程序按钮点击动画效果的实现
2019/09/04 Javascript
微信内置浏览器图片查看器的代码实例
2019/10/08 Javascript
Vue实现简单的跑马灯
2020/05/25 Javascript
Python中bisect的用法
2014/09/23 Python
python+selenium开发环境搭建图文教程
2017/08/11 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
python实现对输入的密文加密
2019/03/20 Python
详解Python利用random生成一个列表内的随机数
2019/08/21 Python
Python Des加密解密如何实现软件注册码机器码
2020/01/08 Python
friso美素佳儿官方海外旗舰店:荷兰原产原罐
2017/07/03 全球购物
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
英国天然宝石首饰购买网站:Gemondo Jewellery
2018/10/23 全球购物
2014年全国爱牙日宣传活动方案
2014/09/21 职场文书
2015年大学生社会实践评语
2015/03/26 职场文书
故意杀人案辩护词
2015/05/21 职场文书