常见的在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 IDLE加上自动补全和历史功能
Nov 30 Python
使用Python的web.py框架实现类似Django的ORM查询的教程
May 02 Python
CentOS 6.5中安装Python 3.6.2的方法步骤
Dec 03 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
Oct 14 Python
python计算两个矩形框重合百分比的实例
Nov 07 Python
Django choices下拉列表绑定实例
Mar 13 Python
如何基于windows实现python定时爬虫
May 01 Python
python中threading开启关闭线程操作
May 02 Python
python语言的优势是什么
Jun 17 Python
给Django Admin添加验证码和多次登录尝试限制的实现
Jul 26 Python
python Tornado框架的使用示例
Oct 19 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
Feb 23 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+javascript液晶时钟
2006/10/09 PHP
PHP EOT定界符的使用详解
2008/09/30 PHP
Thinkphp使用mongodb数据库实现多条件查询方法
2014/06/26 PHP
PHP可变变量学习小结
2015/11/29 PHP
php生成高清缩略图实例详解
2015/12/07 PHP
详解WordPress开发中的get_post与get_posts函数使用
2016/01/04 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
jquery 插件学习(三)
2012/08/06 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
Jquery中val()表单取值赋值的实例代码
2013/08/15 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
AngularJS内置指令
2015/02/04 Javascript
js代码实现无缝滚动(文字和图片)
2015/08/20 Javascript
总结jQuery插件开发中的一些要点
2016/05/16 Javascript
JavaScript浏览器对象之一Window对象详解
2016/06/03 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
javascript实现5秒倒计时并跳转功能
2019/06/20 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法
2020/12/25 Vue.js
python基础教程之获取本机ip数据包示例
2014/02/10 Python
python脚本设置超时机制系统时间的方法
2016/02/21 Python
Python 如何访问外围作用域中的变量
2016/09/11 Python
Python 2与Python 3版本和编码的对比
2017/02/14 Python
python批量修改图片尺寸,并保存指定路径的实现方法
2019/07/04 Python
基于Python函数和变量名解析
2019/07/19 Python
django将数组传递给前台模板的方法
2019/08/06 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
python 实现兔子生兔子示例
2019/11/21 Python
windows、linux下打包Python3程序详细方法
2020/03/17 Python
flask开启多线程的具体方法
2020/08/02 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
2020/09/23 Python
HTML5之消息通知的使用(Web Notification)
2018/10/30 HTML / CSS
青年创业培训欢迎词
2014/01/08 职场文书
2014年重阳节老干部座谈会局领导发言稿
2014/09/25 职场文书
解决Mysql报错 Table 'mysql.user' doesn't exist
2022/05/06 MySQL