一、单例模式存在的意义

  在这里的单例就是只有一个实例(这里的实例就像在面向对象的时候,创建了一个对象也可以说创建了一个实例),只用一个实例进行程序设计,首先我们可以了解一下什么时候不适合使用单例模式,比如我们需要使用类同时创建多个对象的时候,且每个对象中封装了不同的数据的时候,就不能使用单例模式,就像下面的例子

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设计模式-单例模式的更多相关文章

  1. 《转》Python学习(19)-python函数(二)-关于lambda

    转自http://www.cnblogs.com/BeginMan/p/3178103.html 一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称 ...

  2. Python学习-19.Python的Http模块

    模拟 http 请求是比较常见的一种需求,在 Python 中,使用 http 模块操作. import http.client # 创建 Http 连接. http = http.client.HT ...

  3. Python学习day09 - Python进阶(3)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  4. Python学习day05 - Python基础(3) 格式化输出和基本运算符

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  5. 【Python学习之八】设计模式和异常

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.设计模式1.单例模式确保某一个类只有一个实例, ...

  6. Python学习笔记—Python基础1 介绍、发展史、安装、基本语法

    第一周学习笔记: 一.Python介绍      1.Python的创始人为吉多·范罗苏姆.1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...

  7. Python学习day07 - Python进阶(1) 内置方法

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  8. python学习笔记-python程序运行

    小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...

  9. Python学习(一) Python安装配置

    我本身是Java程序猿,听说Python很强大,所以准备学习一下Python,虽说语言都是相同的,但java跟python肯定还是有区别的.希望在此记录一下自己的学习过程. 目前,Python分2.X ...

  10. python学习: 优秀Python学习资源收集汇总--转

    Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl ...

随机推荐

  1. js之yeild

    1.万恶的回调 对前端工程师来说,异步回调是再熟悉不过了,浏览器中的各种交互逻辑都是通过事件回调实现的,前端逻辑越来越复杂,导致回调函数越来越多,同时 nodejs 的流行也让 javascript ...

  2. HTML学习---基础知识学习

    1.1. HTML 1.为什么要有HTML? "Hello" "<h1>Hello</h1>" - 浏览器渲染时使用一套HTML规则, ...

  3. Mysql学习---索引的学习 180101

    索引:约束 + 快速查找 索引是数据库中用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 问:为什么索引可以这么快?[类似 ...

  4. c/c++ 中#ifndef和#endif的作用及使用

    有时候我们在编程的时候,希望有些代码在我们需要时编译,不需要时不编译,也就是让它快速注释,这时候即可以考虑#ifdef和#endif,它们会使我们的编译器进行选择性编译.使用方法如下: #includ ...

  5. codeforces 407D Largest Submatrix 3

    codeforces 407D Largest Submatrix 3 题意 找出最大子矩阵,须满足矩阵内的元素互不相等. 题解 官方做法 http://codeforces.com/blog/ent ...

  6. 网络Socket编程(简易qq实现之C/S通信1)

    1. 目标:实现两个用户之间的通信,利用的是简单的Socket知识以及简略界面 2. 界面:分为客户端与服务器端(如下图) 3. 基本功能:客户端先向服务器端发送一个消息,这样就可以让客户端与服务器端 ...

  7. iOS UI的几种模式

    iOS UI的几种模式: 1.平凡模式(原生控件组合): 2.新闻模式: 3.播放器模式: 4.微博模式:

  8. BZOJ3208:花神的秒题计划Ⅰ(记忆化搜索DP)

    Description 背景[backboard]: Memphis等一群蒟蒻出题中,花神凑过来秒题……   描述[discribe]: 花花山峰峦起伏,峰顶常年被雪,Memphis打算帮花花山风景区 ...

  9. Python3安装scrapy框架步骤

    Python3安装scrapy框架步骤 1.       安装wheel a)     Pip install wheel 2.       安装lxml Pip install lxml 3.    ...

  10. programming-languages学习笔记--第7部分

    programming-languages学习笔记–第7部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...