Python学习:Python设计模式-单例模式
一、单例模式存在的意义
在这里的单例就是只有一个实例(这里的实例就像在面向对象的时候,创建了一个对象也可以说创建了一个实例),只用一个实例进行程序设计,首先我们可以了解一下什么时候不适合使用单例模式,比如我们需要使用类同时创建多个对象的时候,且每个对象中封装了不同的数据的时候,就不能使用单例模式,就像下面的例子
class Person:
def __init__(self, name, age):
self.name = name
self.age = age zhangsan = Person('张三', 21)
lisi = Person('李四', 38)
wangwu = Person('王五', 37)
那么什么时候适合使用单例模式,如果每个对象中封装了相同的数据,但是需要创建多个对象的时候,而且这两个实例所有的功能是一样的,所以我们就可以使用一个实例完成,在这里我们就可以使用单例模式,如下
class Person:
def __init__(self):
self.name = '123'
self.age = '20' def f1(self):
pass def f2(self):
pass zhangsan = Person()
zhangsan.f1() lisi = Person()
lisi.f1()
为什么要使用单例模式,就是为了在封装数据相同的情况下,而且每个实例可执行的方法相同的时候,不必创建多个对象,只需要使用一个实例,来完成多个相同实例所完成的功能,通过这种方式减少内存的使用。
二、单例模式应用的场景
- 需要频繁的进行创建和销毁的对象;
- 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
- 工具类对象;
- 频繁访问数据库或文件的对象。
三、单例模式的优点以及缺点
优点
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
由于单例模式在内存中只有一个实例,减少了内存开销。
单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
单例模式可以在系统设置全局的访问点,优化和共享资源访问。
其中使用到单例模式时,考虑较多的就是多线程的情况下如何防止被多线程同时创建等问题。
当这个类的对象在多个地方创建的时候,使得内部的方法多次调用,但是希望只要一个对象操作这个方法,或者不希望多个地方同时调用这个方法,需要保持这个方法的单一性质,就用单例模式。
缺点
使用单例模式,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
四、单例模式代码编写
接下来我们就模拟一个数据库连接池来实现单例模式
首先我们介绍一下数据库连接池
我们通过程序进行数据库的操作的时候,每次都需要连接数据库,但是连接数据库需要消耗较多的时间,所以我们可以在我们主机的内存里维护一个数据库连接池,在这个连接池中有若干个已经连接数据库的连接,我们想要连接数据库的时候直接到连接池中取出一个连接即可,省去了连接的时间。
非单例模式
import random class SqlConnectionPool:
__instance = None def __init__(self):
self.ip = '127.0.0.1'
self.port = 3306
self.pwd = '123456'
self.username = 'jhong'
# 去连接
self.conn_list = [1, 2, 3, 4, 5, 6, 7, 8] def get_connection(self):
# 获取连接
r = random.randrange(1, 9)
return r # 我们创建多个对象内存地址是一样的,说明拿到的是同一个对象
obj = SqlConnectionPool()
print(obj)
obj1 = SqlConnectionPool()
print(obj1)
obj2 = SqlConnectionPool()
print(obj2)
输出结果:
可以发现非单例模式每次内存输出的结果都不同,下面是单例模式:
import random class SqlConnectionPool:
__instance = None def __init__(self):
self.ip = '127.0.0.1'
self.port = 3306
self.pwd = '123456'
self.username = 'jhong'
# 去连接
self.conn_list = [1, 2, 3, 4, 5, 6, 7, 8] @staticmethod # 静态方法是由类调用的
def get_instance():
if SqlConnectionPool.__instance:
return SqlConnectionPool.__instance
else:
# 创建一个对象,并将对象赋值给静态字段__instance
SqlConnectionPool.__instance = SqlConnectionPool()
return SqlConnectionPool.__instance # 单例模式关键代码解析
# 当第一次调用这个静态方法的时候,判断__instance的值是None所以执行else,然后在else中创建一个对象赋值给静态字段__instance,然后返回这个静态字段
# 第二次调用这个静态方法的时候,判断__instance的值为真,所以直接返回这个静态字段,而这个静态字段中包含的是第一次创建的对象,所以在以后调用这个方法就只会调用第一次创建的对象,这就是单例模式
def get_connection(self):
# 获取连接
r = random.randrange(1, 9)
return r # 我们创建多个对象内存地址是一样的,说明拿到的是同一个对象
obj = SqlConnectionPool.get_instance()
print(obj)
obj1 = SqlConnectionPool.get_instance()
print(obj1)
obj2 = SqlConnectionPool.get_instance()
print(obj2)
输出结果:
以上是基于类,使用静态字段和静态方法实现的一个单例模式。
Python学习:Python设计模式-单例模式的更多相关文章
- 1 python学习——python环境配置
1 python学习--python环境配置 要学习python语言,光看书看教程还是不好,得动手去写.当然,不管学习什么编程语言,最佳的方式还在于实践. 要实践,先得有一个Python解释器来解释执 ...
- Python学习---Python安装与基础1205
1.0. 安装 1.1.1. 下载 官网下载地址:https://www.python.org/downloads/release/python-352/ 1.1.2. 配置环境变量 因为在安装的时候 ...
- Python学习---Python下[元组]的学习
元组是不可变的, 用小括号()定义,而且一旦定义 ,不可变[类型是tuple] [元组看做一个整体,不可拆分,不可赋值,但可以全部重新赋值] 通过圆括号,用逗号分隔,常用在使语句或用户定义的函数能够安 ...
- Python学习--Python基础语法
第一个Python程序 交互式编程 交互式编程不需要创建脚本文件,是通过 Python 解释器的交互模式进来编写代码. linux上你只需要在命令行中输入 Python 命令即可启动交互式编程,提示窗 ...
- python学习-python入门
开始学习python,开始记录. 第一个小程序:登陆系统 功能:1.通过文件名和密码导入用户名和密码~ 2.用户输入用户名和密码 3.将用户输入的用户名进行比对,先判断用户名是否在黑名单里面,如果在黑 ...
- Python学习---Python的异步IO[all]
1.1.1. 前期环境准备和基础知识 安装: pip3 install aiohttp pip3 install grequests pip3 install wheel pip3 install s ...
- Python学习:python网址收集
Python学习网址收集: 语法学习:http://www.cnblogs.com/hongten/tag/python/ http://www.liaoxuefeng.com ...
- python学习--python 连接SQLServer数据库(两种方法)
1. python 学习.安装教程参照: http://www.runoob.com/python/python-tutorial.html 2. 集成开发环境 JetBrains PyCharm C ...
- Python学习--Python的了解与安装
Python简介: Python 是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python 由荷兰人Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 19 ...
- Python学习 :反射 & 单例模式
反射 什么是反射? - 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) 面向对象中的反射 - 通过字符串的形式来操作(获取.检查.增加.删除)对象中的成员 - python中的 ...
随机推荐
- selenium-模拟鼠标
需要导入的包: from selenium.webdriver import ActionChains 一.模拟鼠标右键 ActionChains(self.driver).context_click ...
- python 并发编程 同步调用和异步调用 回调函数
提交任务的两张方式: 1.同步调用 2.异步调用 同步调用:提交完任务后,就在原地等待任务执行完后,拿到结果,再执行下一行代码 同步调用,导致程序串行执行 from concurrent.future ...
- iOS模拟器发生了崩溃,去哪找Crash Log
iOS模拟器发生了崩溃,可以在如下地方找到崩溃日志: ~/Library/Logs/DiagnosticReports/
- C语言--浮点数
在程序中使用浮点数 -- 浮点数的精确性有限 -- 在从c语言中float类型的精确度只到小数点的7位 -- 浮点数只能在一定范围内去相信它 -- 在有精确度高的要求下不要使用浮点数(在算钱的时候,误 ...
- Go基础学习
Go基础学习 go的基础语法 fmt.Println("hello world!") //go采用行分隔符 关键字 下面列举了 Go 代码中会使用到的 25 个关键字或保留字: b ...
- StanfordNLP for JAVA demo
最近工作需要,研究学习 NLP ,但是 苦于官方文档太过纷繁,容易找不到重点,于是打算自己写一份学习线路 NLP 路线图 好博客韩小阳 斯坦福NLP公开课 统计学习方法 好博客 链接地址:https: ...
- python接口自动化 - Requests-3 高级用法
高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...
- Malloc与Free不调用构造函数与析构函数
例子: #include "stdafx.h" #include <new> #include <iostream> using namespace std ...
- WPF C# 字符串读写文件
WPF C# 字符串读写文件 public class 字符串读写文件 { /// <summary> /// Encoding.Unicode.GetString 如果使用Encodin ...
- kbd_mode - 显示或者设置键盘模式
总览 (SYNOPSIS) kbd_mode [ -auks ] 描述 (DESCRIPTION) 如果 没有 参数 kbd_mode 会 显示 当前 键盘 的 模式, 如果 有 参数, 它会把 键盘 ...