Python单例模式的四种创建方式实例解析


Posted in Python onMarch 04, 2020

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

在 Python 中,我们可以用多种方法来实现单例模式:

  • 使用模块
  • 使用__new__使
  • 用装饰器(decorator)
  • 使用元类(metaclass)

使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

Python单例模式的四种创建方式实例解析

将上面的代码保存在文件mysingleton.py中,然后这样使用:

Python单例模式的四种创建方式实例解析

使用__new__

为了使类只能出现一个实例,我们可以使用__new__来控制实例的创建过程,代码如下:

Python单例模式的四种创建方式实例解析

在上面的代码中,我们将类的实例和一个类变量_instance关联起来,如果cls._instance为 None 则创建实例,否则直接返回cls._instance。

执行情况如下:

Python单例模式的四种创建方式实例解析

使用装饰器

我们知道,装饰器(decorator)可以动态地修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例,代码如下:

Python单例模式的四种创建方式实例解析

在上面,我们定义了一个装饰器singleton,它返回了一个内部函数getinstance,该函数会判断某个类是否在字典instances中,如果不存在,则会将cls作为 key,cls(*args, **kw)作为 value 存到instances中,否则,直接返回instances[cls]。

使用 metaclass

元类(metaclass)可以控制类的创建过程,它主要做三件事:

拦截类的创建修改类的定义返回修改后的类

使用元类实现单例模式的代码如下:

Python单例模式的四种创建方式实例解析

小结Python 的模块是天然的单例模式,这在大部分情况下应该是够用的,当然,我们也可以使用装饰器、元类等方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
学习python的几条建议分享
Feb 10 Python
python中常用的各种数据库操作模块和连接实例
May 29 Python
简单介绍Python中的RSS处理
Apr 13 Python
python删除指定类型(或非指定)的文件实例详解
Jul 06 Python
Python中规范定义命名空间的一些建议
Jun 04 Python
Tornado高并发处理方法实例代码
Jan 15 Python
Python实现简单生成验证码功能【基于random模块】
Feb 10 Python
TensorFlow实现Batch Normalization
Mar 08 Python
flask session组件的使用示例
Dec 25 Python
Django 数据库同步操作技巧详解
Jul 19 Python
Python如何实现FTP功能
May 28 Python
Python之matplotlib绘制折线图
Apr 13 Python
通过实例解析Python return运行原理
Mar 04 #Python
Python递归函数特点及原理解析
Mar 04 #Python
Mac中PyCharm配置Anaconda环境的方法
Mar 04 #Python
python实现简单井字棋游戏
Mar 04 #Python
pycharm中import呈现灰色原因的解决方法
Mar 04 #Python
使用Pyhton 分析酒店针孔摄像头
Mar 04 #Python
pycharm新建Vue项目的方法步骤(图文)
Mar 04 #Python
You might like
php统计文件大小,以GB、MB、KB、B输出
2011/05/29 PHP
PHP批量去除BOM头内容信息代码
2016/03/11 PHP
利用PHPExcel读取Excel的数据和导出数据到Excel
2017/05/12 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
jQuery创建插件的代码分析
2011/04/14 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
2014/05/08 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
JavaScript中的对象的extensible属性介绍
2014/12/30 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
2015/07/05 Javascript
jquery实现图片水平滚动效果代码分享
2015/08/26 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
基于jQuery1.9版本如何判断浏览器版本类型
2016/01/12 Javascript
JavaScript将base64图片转换成formData并通过AJAX提交的实现方法
2016/10/24 Javascript
html判断当前页面是否在iframe中的实例
2016/11/30 Javascript
linux 后台运行node服务指令方法
2018/05/23 Javascript
vue根据进入的路由进行原路返回的方法
2018/09/26 Javascript
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
Python易忽视知识点小结
2015/05/25 Python
python3实现读取chrome浏览器cookie
2016/06/19 Python
13个最常用的Python深度学习库介绍
2017/10/28 Python
Python基础教程之内置函数locals()和globals()用法分析
2018/03/16 Python
python+POP3实现批量下载邮件附件
2018/06/19 Python
python调用java的jar包方法
2018/12/15 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
2019/02/13 Python
django admin.py 外键,反向查询的实例
2019/07/26 Python
详解用Python为直方图绘制拟合曲线的两种方法
2019/08/21 Python
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
python_array[0][0]与array[0,0]的区别详解
2020/02/18 Python
PyTorch中的拷贝与就地操作详解
2020/12/09 Python
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
数组越界问题
2015/10/21 面试题
方正Java笔试题
2014/07/03 面试题
新学期决心书
2014/03/11 职场文书
Python利用zhdate模块实现农历日期处理
2022/03/31 Python
css样式important规则的正确使用方式
2022/06/10 HTML / CSS