Python学习:19.Python设计模式-单例模式
一、单例模式存在的意义
在这里的单例就是只有一个实例(这里的实例就像在面向对象的时候,创建了一个对象也可以说创建了一个实例),只用一个实例进行程序设计,首先我们可以了解一下什么时候不适合使用单例模式,比如我们需要使用类同时创建多个对象的时候,且每个对象中封装了不同的数据的时候,就不能使用单例模式,就像下面的例子
class Person:
def __init__(self,name,age):
self.name = name
self.age = age mingming = Person('明明',19)
mingyue = Person('明月',30)
mingri = Person('明日',20)
那么什么时候适合使用单例模式,如果每个对象中封装了相同的数据,但是需要创建多个对象的时候,而且这两个实例所有的功能是一样的,所以我们就可以使用一个实例完成,在这里我们就可以使用单例模式,如下
class Person:
def __init__(self):
self.name = ''
self.age = '' def f1(self):
pass def f2(self):
pass mingming = Person()
mingming.f1() mingyue = Person()
mingyue.f1()
为什么要使用单例模式,就是为了在封装数据相同的情况下,而且每个实例可执行的方法相同的时候,不必创建多个对象,只需要使用一个实例,来完成多个相同实例所完成的功能,通过这种方式减少内存的使用。
二、单例模式应用的场景
- 需要频繁的进行创建和销毁的对象;
- 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
- 工具类对象;
- 频繁访问数据库或文件的对象。
三、单例模式的优点以及缺点
优点
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
由于单例模式在内存中只有一个实例,减少了内存开销。
单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
单例模式可以再系统设置全局的访问点,优化和共享资源访问。
其中使用到单例模式时,考虑较多的就是多线程的情况下如何防止被多线程同时创建等问题。
当这个类的对象在多个地方创建的时候,使得内部的方法多次调用,但是希望只要一个对象操作这个方法,或者不希望多个地方同时调用这个方法,需要保持这个方法的单一性质,就用单利模式
缺点
使用单例模式,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
四、单例模式代码编写
接下来我们就模拟一个数据库连接池来实现单例模式
首先我们介绍一下数据库连接池
我们通过程序进行数据库的操作的时候,每次都需要连接数据库,但是连接数据库需要消耗较多的时间,所以我们可以在我们主机的内存里维护一个数据库连接池,在这个连接池中有若干个已经连接数据库的连接,我们想要连接数据库的时候直接到连接池中取出一个连接即可,省去了连接的时间。
非单例模式
import random
class SqlConnectionPool:
__instance = None
def __init__(self):
self.ip = "127.0.0.1"
self.port = 3306
self.pwd = ''
self.username = 'alexsel'
#去连接
self.conn_list = [1,2,3,4,5,6,7,8,9,10]
def get_connection(self):
#获取连接
r = random.randrange(1,11)
return r
#我们创建多个对象内存地址是一样的,说明拿到的是同一个对象
obj = SqlConnectionPool()
print(obj)
obj1 = SqlConnectionPool()
print(obj1)
obj2 = SqlConnectionPool()
print(obj2)
输出结果:
<__main__.SqlConnectionPool instance at 0x0000000002630788>
<__main__.SqlConnectionPool instance at 0x0000000002630888>
<__main__.SqlConnectionPool instance at 0x00000000026308C8>
非单例模式每次内存输出的结果都不同,下面是单例模式。
import random
class SqlConnectionPool:
__instance = None
def __init__(self):
self.ip = "127.0.0.1"
self.port = 3306
self.pwd = ''
self.username = 'alexsel'
#去连接
self.conn_list = [1,2,3,4,5,6,7,8,9,10]
@staticmethod #静态方法是由类调用的
def get_instance():
if SqlConnectionPool.__instance:
return SqlConnectionPool.__instance
else:
#创建一个对象,并将对象赋值给静态字段__instance
SqlConnectionPool.__instance = SqlConnectionPool()
return SqlConnectionPool.__instance
#单例模式关键代码解析
#当第一次调用这个静态方法的时候,判断__instacne的值是None所以执行else,然后在else中创建一个对象赋给静态字段__instance,然后返回这个静态字段
#第二次调用这个今静态方法的时候,判断__instance的值为真,所以直接返回这个静态字段,而这个静态字段中包含的是第一次创建的对象,所以在以后调用这个方法
#就只会调用第一次创建的对象,这就是单例模式
def get_connection(self):
#获取连接
r = random.randrange(1,11)
return r
#我们创建多个对象内存地址是一样的,说明拿到的是同一个对象
obj = SqlConnectionPool.get_instance()
print(obj)
obj1 = SqlConnectionPool.get_instance()
print(obj1)
obj2 = SqlConnectionPool.get_instance()
print(obj2)
输出结果:
<__main__.SqlConnectionPool instance at 0x000000000260C808>
<__main__.SqlConnectionPool instance at 0x000000000260C808>
<__main__.SqlConnectionPool instance at 0x000000000260C808>
以上是基于类,使用静态字段和静态方法实现的一个单例模式。
Python学习:19.Python设计模式-单例模式的更多相关文章
- 《转》Python学习(19)-python函数(二)-关于lambda
转自http://www.cnblogs.com/BeginMan/p/3178103.html 一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称 ...
- Python学习-19.Python的Http模块
模拟 http 请求是比较常见的一种需求,在 Python 中,使用 http 模块操作. import http.client # 创建 Http 连接. http = http.client.HT ...
- Python学习day09 - Python进阶(3)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- Python学习day05 - Python基础(3) 格式化输出和基本运算符
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- 【Python学习之八】设计模式和异常
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.设计模式1.单例模式确保某一个类只有一个实例, ...
- Python学习笔记—Python基础1 介绍、发展史、安装、基本语法
第一周学习笔记: 一.Python介绍 1.Python的创始人为吉多·范罗苏姆.1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...
- Python学习day07 - Python进阶(1) 内置方法
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- python学习笔记-python程序运行
小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...
- Python学习(一) Python安装配置
我本身是Java程序猿,听说Python很强大,所以准备学习一下Python,虽说语言都是相同的,但java跟python肯定还是有区别的.希望在此记录一下自己的学习过程. 目前,Python分2.X ...
- python学习: 优秀Python学习资源收集汇总--转
Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl ...
随机推荐
- SQL一次性查询一个字段不同条件下的统计结果
参考了一下这篇文章:https://blog.csdn.net/xichenguan/article/details/51764100 , 感谢原作者 有两个表,分别存放了[操作员]和[单据],要根据 ...
- Hadoop配置文件详解
1 获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知 ...
- Python学习---迭代器学习1210
可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的generator fun ...
- js的一道经典题目
今天碰到一道题,里面既包含了匿名函数的知识,也包含了预编译,函数的传参(形参),感觉迷迷糊糊的,所以想着做个总结. var foo={n:1}; (function(foo){ console.log ...
- Android SDK 墙内更新方法
1.访问地址:http://ping.chinaz.com/,在网站测速处输入g.cn执行查看分析,如下图所示 2.在分析列表中找到速度最快的IP复制进行设置SDK代理并设置端口为80,并勾选Forc ...
- socket的双重属性
1)api属性: 2)通信链路的端点属性.
- 远程调用内核接口的封装类(RCKObjs)
RCK 包括 Application, Function, Connection, Command, Response 和 Fields 六 大类, 其主要功能例如以下: a. Applica ...
- 数论——算数基本定理 - HDU 4497 GCD and LCM
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
- NPOI下载
.吐槽NPOI下载 众所周知我们用NPOI第三方程序集主要的目的就是为了能快捷的操作Excel,但是现在不论是官网(https://archive.codeplex.com/?p=npoi)还是git ...
- 404 Note Found 队-Alpha1
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...