常见的在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正则式
May 07 Python
利用Python爬取可用的代理IP
Aug 18 Python
python导入csv文件出现SyntaxError问题分析
Dec 15 Python
Python数据结构与算法之常见的分配排序法示例【桶排序与基数排序】
Dec 15 Python
Python解析、提取url关键字的实例详解
Dec 17 Python
GitHub 热门:Python 算法大全,Star 超过 2 万
Apr 29 Python
Python使用Pandas对csv文件进行数据处理的方法
Aug 01 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
Aug 05 Python
Python使用matplotlib 画矩形的三种方式分析
Oct 31 Python
Python性能分析工具Profile使用实例
Nov 19 Python
keras读取h5文件load_weights、load代码操作
Jun 12 Python
python实现经典排序算法的示例代码
Feb 07 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语法速查表
2006/12/06 PHP
thinkphp浏览历史功能实现方法
2014/10/29 PHP
PHP使用fopen与file_get_contents读取文件实例分享
2016/03/04 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
Yii2框架中使用PHPExcel导出Excel文件的示例
2017/08/09 PHP
js中的布尔运算符使用介绍
2013/11/20 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
2014/01/07 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
2016/10/18 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
2020/12/01 Javascript
ExtJs异步无法向外传值和赋值的完美解决办法
2017/06/14 Javascript
jQuery实现表格冻结顶栏效果
2017/08/20 jQuery
element-ui上传一张图片后隐藏上传按钮功能
2019/05/22 Javascript
JS实现动态添加外部js、css到head标签的方法
2019/06/05 Javascript
vue.config.js常用配置详解
2019/11/14 Javascript
如何在vue中使用百度地图添加自定义覆盖物(水波纹)
2020/11/03 Javascript
[46:58]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第一场 12.17
2020/12/19 DOTA
利用Python的Django框架生成PDF文件的教程
2015/07/22 Python
Python网络编程基于多线程实现多用户全双工聊天功能示例
2018/04/10 Python
python3+opencv3识别图片中的物体并截取的方法
2018/12/05 Python
python从子线程中获得返回值的方法
2019/01/30 Python
强悍的Python读取大文件的解决方案
2019/02/16 Python
Python 3.8新特征之asyncio REPL
2019/05/28 Python
12个Python程序员面试必备问题与答案(小结)
2019/06/24 Python
python数据持久存储 pickle模块的基本使用方法解析
2019/08/30 Python
分享一个python的aes加密代码
2020/12/22 Python
CSS3媒体查询Media Queries基础学习教程
2016/02/29 HTML / CSS
Conforama瑞士:家具、厨房、电器、装饰
2020/09/06 全球购物
幼儿园大班毕业教师寄语
2014/04/03 职场文书
关于环保的演讲稿
2014/05/10 职场文书
安全目标责任书
2014/07/22 职场文书
大学新生军训自我鉴定范文
2014/09/13 职场文书
高中生个性发展自我评价
2015/03/09 职场文书
2016年第十九届推普周活动总结
2016/04/06 职场文书
导游词之无锡梅园
2019/11/28 职场文书
JavaScript+HTML实现学生信息管理系统
2021/04/20 Javascript
JavaScript实现淘宝商品图切换效果
2021/04/29 Javascript