常见的在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 相关文章推荐
Python3实现腾讯云OCR识别
Nov 27 Python
python 基于TCP协议的套接字编程详解
Jun 29 Python
python做反被爬保护的方法
Jul 01 Python
教你如何编写、保存与运行Python程序的方法
Jul 12 Python
Python Django基础二之URL路由系统
Jul 18 Python
django的model操作汇整详解
Jul 26 Python
python matplotlib 画dataframe的时间序列图实例
Nov 20 Python
使用Python串口实时显示数据并绘图的例子
Dec 26 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
Jan 02 Python
Django自定义列表 models字段显示方式
Apr 03 Python
详解Anaconda 的安装教程
Sep 23 Python
Pytorch中使用ImageFolder读取数据集时忽略特定文件
Mar 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与SQL注入攻击[一]
2007/04/17 PHP
destoon在各个服务器下设置URL Rewrite(伪静态)的方法
2014/06/21 Servers
smarty简单入门实例
2014/11/28 PHP
PHPstorm启用自动换行的方法详解(IDE)
2020/09/17 PHP
js loading加载效果实现代码
2009/11/24 Javascript
jquery实现textarea输入字符控制(仿微博输入控制字符)
2013/04/26 Javascript
如何使用jQUery获取选中radio对应的值(一句代码)
2013/06/03 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
AngularJS入门示例之Hello World详解
2017/01/04 Javascript
Angular.Js中ng-include指令的使用与实现
2017/05/07 Javascript
详解vue mixins和extends的巧妙用法
2017/12/20 Javascript
JavaScript体验异步更好的解决办法
2018/01/08 Javascript
一次记住JavaScript的6个正则表达式方法
2018/02/22 Javascript
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python中使用序列的方法
2015/08/03 Python
Python操作Excel之xlsx文件
2017/03/24 Python
python读取excel指定列数据并写入到新的excel方法
2018/07/10 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
对DJango视图(views)和模版(templates)的使用详解
2019/07/17 Python
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
Python实现手绘图效果实例分享
2020/07/22 Python
如何在 Matplotlib 中更改绘图背景的实现
2020/11/26 Python
如何编写优秀的食品项目创业计划书
2014/01/23 职场文书
大专生自我评价
2014/01/28 职场文书
致长跑运动员广播稿
2014/01/31 职场文书
小学语文教学经验交流材料
2014/06/02 职场文书
绘画专业自荐信
2014/07/04 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
化妆品促销活动总结
2015/05/07 职场文书
给朋友的赠语
2015/06/23 职场文书
青年人初次创业的“五不要”
2019/08/23 职场文书
使用canvas实现雪花飘动效果的示例代码
2021/03/30 HTML / CSS
DE1103使用报告
2022/04/05 无线电