常见的在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中的一些类型转换函数小结
Feb 10 Python
Python的__builtin__模块中的一些要点知识
May 02 Python
利用Celery实现Django博客PV统计功能详解
May 08 Python
深入理解Python中的内置常量
May 20 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
Jul 06 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
Nov 08 Python
python实时监控cpu小工具
Jun 21 Python
python实现PID算法及测试的例子
Aug 08 Python
Python函数参数类型及排序原理总结
Dec 19 Python
Python字典添加,删除,查询等相关操作方法详解
Feb 07 Python
Python3列表List入门知识附实例
Feb 09 Python
python连接手机自动搜集蚂蚁森林能量的实现代码
Feb 24 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
Uchome1.2 1.5 代码学习 common.php
2009/04/24 PHP
PHP以及MYSQL日期比较方法
2012/11/29 PHP
php数据类型判断函数有哪些
2013/09/23 PHP
php计算当前程序执行时间示例
2014/04/24 PHP
采用memcache在web集群中实现session的同步会话
2014/07/05 PHP
php将html转为图片的实现方法
2017/05/19 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
PJ Blog修改-禁止复制的代码和方法
2006/10/25 Javascript
javascript 简单高效判断数据类型 系列函数 By shawl.qiu
2007/03/06 Javascript
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
2007/08/13 Javascript
javascript 隐藏/显示指定的区域附HTML元素【legend】用法
2010/03/05 Javascript
编写自己的jQuery插件简单实现代码
2011/04/19 Javascript
javascript 进阶篇1 正则表达式,cookie管理,userData
2012/03/14 Javascript
jQuery检查事件是否触发的方法
2015/06/26 Javascript
jQuery Validate插件实现表单验证
2016/08/19 Javascript
JS验证全角与半角及相互转化的介绍
2017/05/18 Javascript
详解vue项目优化之按需加载组件-使用webpack require.ensure
2017/06/13 Javascript
详解如何在Vue项目中导出Excel
2019/04/19 Javascript
vue 父组件中调用子组件函数的方法
2019/06/06 Javascript
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Python模拟登录之滑块验证码的破解(实例代码)
2019/11/18 Python
使用python实现飞机大战游戏
2020/03/23 Python
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
Zavvi荷兰:英国大型音像制品和图书游戏零售商
2018/03/22 全球购物
澳大利亚运动鞋零售商:The Athlete’s Foot
2018/11/04 全球购物
硕士研究生求职自荐信范文
2014/03/11 职场文书
函授本科个人自我鉴定
2014/03/25 职场文书
烹饪大赛策划方案
2014/05/26 职场文书
2014年涉外离婚协议书范本
2014/11/20 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
入团介绍人意见范文
2015/06/04 职场文书
蓝天保卫战收官在即 :15行业将开展环保分级评价
2019/07/19 职场文书
Nginx开启Brotli压缩算法实现过程详解
2021/03/31 Servers
SQL Server基本使用和简单的CRUD操作
2021/04/05 SQL Server
python实现双向链表原理
2022/05/25 Python