常见的在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正则表达式中的括号匹配问题
Dec 14 Python
Python提取Linux内核源代码的目录结构实现方法
Jun 24 Python
python中 logging的使用详解
Oct 25 Python
python实现外卖信息管理系统
Jan 11 Python
numpy中矩阵合并的实例
Jun 15 Python
python scatter散点图用循环分类法加图例
Mar 19 Python
python自动化测试之异常及日志操作实例分析
Nov 09 Python
Transpose 数组行列转置的限制方式
Feb 11 Python
python tkiner实现 一个小小的图片翻页功能的示例代码
Jun 24 Python
Pycharm的Available Packages为空的解决方法
Sep 18 Python
python状态机transitions库详解
Jun 02 Python
Pandas实现DataFrame的简单运算、统计与排序
Mar 31 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
新浪微博OAuth认证和储存的主要过程详解
2015/03/27 PHP
实例详解PHP中html word 互转的方法
2016/01/28 PHP
PHP数据库表操作的封装类及用法实例详解
2016/07/12 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
js jquery验证银行卡号信息正则学习
2013/01/21 Javascript
JavaScript制作的可折叠弹出式菜单示例
2014/04/04 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
微信小程序 绘图之饼图实现
2016/10/24 Javascript
详解JavaScript跨域总结与解决办法
2016/10/31 Javascript
BootStrap实现响应式布局导航栏折叠隐藏效果(在小屏幕、手机屏幕浏览时自动折叠隐藏)
2016/11/30 Javascript
浅谈javascript的url参数parse和build函数
2017/03/04 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
vue中$nextTick的用法讲解
2019/01/17 Javascript
[01:17]炒鸡美酒第四天TA暴走
2018/06/05 DOTA
深入理解Python 代码优化详解
2014/10/27 Python
python中reduce()函数的使用方法示例
2017/09/29 Python
基于python实现在excel中读取与生成随机数写入excel中
2018/01/04 Python
python3.6+django2.0+mysql搭建网站过程详解
2019/07/24 Python
python flask web服务实现更换默认端口和IP的方法
2019/07/26 Python
Python 根据日志级别打印不同颜色的日志的方法示例
2019/08/08 Python
Django ORM多对多查询方法(自定义第三张表&ManyToManyField)
2019/08/09 Python
python垃圾回收机制(GC)原理解析
2019/12/30 Python
PyQt5中向单元格添加控件的方法示例
2020/03/24 Python
Python实现迪杰斯特拉算法过程解析
2020/09/18 Python
pycharm实现猜数游戏
2020/12/07 Python
Does C# support multiple inheritance? (C#支持多重继承吗)
2012/01/04 面试题
用Java语言将一个键盘输入的数字转化成中文输出
2013/01/25 面试题
国旗下演讲稿
2014/05/08 职场文书
动物科学专业求职信
2014/07/27 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
一文读懂navicat for mysql基础知识
2021/05/31 MySQL
Python多个MP4合成视频的实现方法
2021/07/16 Python