一. 单例模式(Singleton)

所谓单例模式,也就是说不管什么时候都要确保只有一个对象实例存在。很多情况下,整个系统中只需要存在一个对象,所有的信息都从这个对象获取,比如系统的配置对象,或者是线程池。这些场景下,就非常适合使用单例模式。

总结起来,就是说不管初始化一个对象多少次,真正干活的对象只会生成一次并且在首次生成。

用Python 实现单例模式的方法有很多,先来看第一种方式。

# !/usr/bin/python3
# -*- coding:utf-8 -*- class singleton(object):
"""
单列模式
""" class _A(object):
"""
真正干活的类,对外隐藏。
""" def __init__(self):
pass def display(self):
""" 返回当前实例的ID,是全局唯一的"""
return id(self) # 类变量,用于存储_A 的实例
_instance = None def __init__(self):
""" 先判断类变量中是否已经保存了_A 的实例,如果没有则创建一个后返回"""
if singleton._instance is None:
singleton._instance = singleton._A() def __getattr__(self, attr):
return getattr(self._instance, attr) if __name__ == "__main__":
# 创建2个实例
s1 = singleton()
s2 = singleton()
print(id(s1), s1.display())
print(id(s2), s2.display())

# !/usr/bin/python3 # -*- coding:utf-8 -*- class singleton(object): """ 单列模式 """ class _A(object): """ 真正干活的类,对外隐藏。 """ def __init__(self): pass def display(self): """ 返回当前实例的ID,是全局唯一的""" return id(self) # 类变量,用于存储_A 的实例 _instance = None def __init__(self): """ 先判断类变量中是否已经保存了_A 的实例,如果没有则创建一个后返回""" if singleton._instance is None: singleton._instance = singleton._A() def __getattr__(self, attr): return getattr(self._instance, attr) if __name__ == "__main__": # 创建2个实例 s1 = singleton() s2 = singleton() print(id(s1), s1.display()) print(id(s2), s2.display())

Output:

1917919737784 1917919737896
1917919738008 1917919737896

以上的单列模式实现中,借助了使用类变量 Singleton._instance 来存储创建的实例,并且保证只会创建一次实例。由于 Python 是一门动态语言,可以在运行时改变类定义。上面的代码中,在首次初始化 Singleton 时,将首次生成类 _A 的实例,并将其存储到 Singleton._instance 中,以后每次初始化 Singleton 时都从 Singleton._instance 获取真正干活的实例,这样就实现了单例模式。

从输出中可以看到,尽管创建了两个不同的实例(实例 ID 不同),但是访问其属性的时候得到的 ID 是一致的。以上代码虽然很好的实现了单例模式,但是在真正的项目开发中这种方式却不够灵活,因为要将真正干活的类内置在单例类中。 我们知道在 Python 中装饰器很好用,那能否将单例类实现成一个装饰器呢?答案是肯定的,下面实现代码。

# !/usr/bin/python3
# -*- coding:utf-8 -*-
import sqlite3
from flask import current_app
from flask import _app_ctx_stack as stack class SQLite3(object):
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app) def init_app(self, app):
"""典型的 Flask 扩展的初始化方式"""
app.config.setdefault('SQLITE3_DATABASE', ':memory:')
app.teardown_appcontext(self.teardown) def connect(self):
"""连接到 sqlite 数据库"""
return sqlite3.connect(current_app.config['SQLITE3_DATABASE']) def teardown(self, exception):
"""关闭 sqlite 链接"""
ctx = stack.top
if hasattr(ctx, 'sqlite3_db'):
ctx.sqlite3_db.close() @property
def connection(self):
"""
单例模式在这里:使用 flask._app_ctx_stack 存放 sqlite 链接,
每次获取数据库链接时都通过 connection 获取
"""
ctx = stack.top
if ctx is not None:
if not hasattr(ctx, 'sqlite3_db'):
ctx.sqlite3_db = self.connect()
return ctx.sqlite3_db

在以上的代码中,在每次使用数据库的时候通过 SQLite3.connection 获取数据库连接就可以了。SQLite3.connection保证了数据库连接只会发生一次,其原理和之前实现单例模式的方式相同,只不过这里存储实例的地方变成 flask._app_ctx_stack了。

通过以上几段代码,可以看到单例模式的实现只需要找一个变量存放创建的实例,然后每次获取实例时,先检查变量中是否已保存实例,如果没有则创建一个实例并将其存放到变量中,以后都从这个变量中获取实例就可以了。单例模式中,只会创建一次实例。

Python版设计模式: 创建型模式:单例模式和工厂模式家族的更多相关文章

  1. python设计模式---创建型之单例模式

    数据结构和算法是基本功, 设计模式是最佳实现. 作为程序员,必须有空了就练一练哈. # coding = utf-8 """ # 经典单例 class Singleton ...

  2. java设计模式--创建型模式(一)

    2016-04-24 10:10:34 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂 ...

  3. C#设计模式-创建型模式(转)

    一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式 ...

  4. 设计模式(三): FACTORY工厂模式 -- 创建型模式

    1.定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类. 2.适用场景 1.第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体 ...

  5. Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)

    一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...

  6. 设计模式----创建型模式之工厂模式(FactoryPattern)

    工厂模式主要分为三种简单工厂模式.工厂方法模式.抽象工厂模式三种.顾名思义,工厂主要是生产产品,作为顾客或者商家,我们不考虑工厂内部是怎么一个流程,我们要的是最终产品.将该种思路放在我们面向对象开发实 ...

  7. java设计模式 -------- 创建模式 之 抽象工厂模式

    本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 工厂方法模式和抽象工厂模式不好区分清楚: 工厂方法模式特点: 1. 一个抽象产品 ...

  8. python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)

    十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...

  9. PHP面向对象-设计模式 单例模式 简单工厂模式 工厂方法模式

    1.单例模式 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 要实现每一个类只有一个实例,就需 ...

  10. [19/04/23-星期二] GOF23_创建型模式(工厂模式、抽象工厂模式)

    一.工厂模式(分为:简单工厂模式.工厂方法模式.抽象工厂模式) 实现了创建者和调用者的分离 核心本质:1.实例化对象,用工厂方法代替new操作:2.将选择实现类.创建对象统一管理和控制,从而将调用者跟 ...

随机推荐

  1. html+ccs3太阳系行星运转动画之土星有个环,地球有颗小卫星

    在上一篇<html+ccs3太阳系行星运转动画>中实现了太阳系八大行星的基本运转动画. 太阳系又何止这些内容,为丰富一下动画,接下来增加“土星环”和“月球”来充盈太阳系动画. 下面是充盈后 ...

  2. 深度解析C语言int与unsigned int

    就如同int a:一样,int 也能被其它的修饰符修饰.除void类型外,基本数据类型之前都可以加各种类型修饰符,类型修饰符有如下四种:1.signed----有符号,可修饰char.int.Int是 ...

  3. asp.net mvc 上传文件

    转至:http://www.cnblogs.com/fonour/p/ajaxFileUpload.html 0.下载 http://files.cnblogs.com/files/fonour/aj ...

  4. ubuntu安装navicat及常见问题解决

    1.安装navicat Step1: 下载Navicat ,网址:http://www.navicat.com/en/download/download.html Step2:进入下载目录,解压压缩包 ...

  5. MVC跨项目路由

    我们在实际应用开发中,经常遇到多人共同开发维护同一个项目情况,所以不免会出现其中一个人代码出现bug质量问题导致整个项目就原地“爆炸”的惨状.在之前公司经常遇到某个人忘记更新(我就做个此事[" ...

  6. 【JS基础】算法

    Math 对象 Math.sqrt() //返回一个数的平方根

  7. iOS之17个提升iOS开发效率的必用工具

    时间就是金钱.编码效率的提升意味着更多的收入.可是当我们的开发技巧已经到达一定高度时,如何让开发效率更上一层楼呢?答案就是使用开发工具!在这篇文章中,我会向你介绍一些帮助我提升编码速度和工作效率的工具 ...

  8. 简历生成平台项目开发-STEP4第二次项目例会讨论

    时间:2016.7.15周五7点半 地点:图书馆 讨论主题:交流各自手头项目进展,确定下一步任务 内容:按照之前的讨论的任务大家各自汇报进度. 汇报人:谭卓.尹忠诚 内容:1.基于富文本编辑器的模板, ...

  9. Group by

    分组语句必须和聚合函数在一起使用, group by子句负责将数据分成逻辑组,聚合函数对每一组进行统计计算 group by 必须放到 select 语句后面,如果select语句中有where子句, ...

  10. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...