前言

单例模式是创建模式中比较常见和常用的模式,在程序执行的整个生命周期只存在一个实例对象。

系列文章

目录

简单理解

  • 每个类创建实例化对象的时候,保证在同一个上下文环境中确保某一个类只有一个实例,减少内存的开销。

python实现方法

python类的实例是由__new__方法创建的,因此单例要在new方法上做文章。

class Test(object):

    __instance = None

    def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance=object.__new__(cls) # 将实例对象用一个变量引用住,以后每次创建时直接返回该对象
return cls.__instance def __init__(self):
pass class Test(object): __instance = None
__first_one = False def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance=object.__new__(cls)
return cls.__instance def __init__(self, name):
if not self.__first_one: # 使用一个变量的状态来记录__init__的状态,保证只初始化一次,提高运行效率
self.__first_one = True
self.name = name

一般的应用场景

  • 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;比如一个对象创建时有几十上百个属性需要初始化,而初始化参数又不变的;因为object._new_(cls)方法每执行一次就会在内存中创建一个新的实例。
class Test(object):

    __instance = None
__first_one = False def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance=object.__new__(cls)
return cls.__instance def __init__(self, name):
if not self.__first_one: # 使用一个变量的状态来记录__init__的状态,保证只初始化一次,提高运行效率
self.__first_one = True
self.name1 = name
....
self.name100 = "xxxx"
  • 工具类对象;有时为了方便管理工具函数,会让工具函数变成某个类的实例方法,但是在调用的时候要先创建一个实例,所以这个实例可以是一个单例。

  • 频繁访问数据库或文件的对象;由于涉及io操作,耗时较多,所以良好的做法是在内存中维护一个连接池,需要的时候返回一个连接对象。

连接mysql实例

# 以连接mysql为例
from pymysql import * class MysqlManager(object):
pool = [] # 设置连接池
__instance = None
__first_one = False
count = 0 def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance def __init__(self, host,port,database,user,password,charset='utf8',number=5):
if not self.__first_one:
self.__first_one = True
self.number = number
self.pool = [connect(host=host, port=port, database=database,
user=user, password=password, charset=charset) for i in range(number)] def __enter__(self): # 上下文管理器返回一个连接对象
if self.count < self.number:
con = self.pool[self.count]
self.count += 1
return con
else:
self.count = 0
return self.pool[0] def __exit__(self, exc_type, exc_val, exc_tb):
pass def get_cursor(self): # 直接得到一个游标
if self.count < self.number:
con = self.pool[self.count]
self.count += 1
return con.cursor()
else:
self.count = 0
return self.pool[0].cursor()
  • 多线程需要相同的创建的对象,可以使用单例共享资源优化配置。

总结

  1. python单例模式的实现原理主要是另__new__魔法方法和__init__魔法方法每次返回的对象不变即可;

  2. 单例模式主要用在当一些场景不关心实例的属性而只关系实例的方法,即业务需要使用对象的功能,对对象本身的属性不会去改变它。

参考

python设计模式之单例模式(一)的更多相关文章

  1. python设计模式之单例模式(二)

    上次我们简单了解了一下什么是单例模式,今天我们继续探究.上次的内容点这 python设计模式之单例模式(一) 上次们讨论的是GoF的单例设计模式,该模式是指:一个类有且只有一个对象.通常我们需要的是让 ...

  2. python设计模式之单例模式(转)

    设计模式之单例模式 单例设计模式是怎么来的?在面向对象的程序设计中,当业务并发量非常大时,那么就会出现重复创建相同的对象,每创建一个对象就会开辟一块内存空间,而这些对象其实是一模一样的,那么有没有办法 ...

  3. Python设计模式之单例模式

    1.由于语言的特性不同,设计模式的实现方式和实现难度也会不同 2.有的模式已经在语言内置了,比如迭代器模式. 3.单例模式可以直接用模块级变量来实现 4.普通工厂模式可以直接通过传入"类名& ...

  4. python设计模式之单例模式(一)

    单例设计模式的概念: 单例设计模式即确保类有且只有一个特定类型的对象,并提供全局访问点.一般我们操作数据库的时候为了避免统一资源产生互相冲突,创建单例模式可以维护数据的唯一性. 单例模式的特性: 确保 ...

  5. python设计模式之--单例模式

    python的单例模式就是一个类的实例只能自始自终自能创建一次.应用场景比如说数据库的连接池. #!/usr/bin/env python # coding=utf- class Foo(object ...

  6. Python设计模式中单例模式的实现及在Tornado中的应用

    单例模式的实现方式 将类实例绑定到类变量上 class Singleton(object): _instance = None def new(cls, *args): if not isinstan ...

  7. 【python 设计模式】单例模式

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

  8. python 设计模式之 单例模式

    单例模式是做为"全局变量"的替代品出现的.所以它具有全局变量的特点:全局可见.贯穿应用程序的整个生命期,保证在程序执行中,某个类仅仅存在一个实例,所以通常不希望类中的构造函数被调用 ...

  9. python 设计模式之单例模式 Singleton Pattern

    #引入 一个类被设计出来,就意味着它具有某种行为(方法),属性(成员变量).一般情况下,当我们想使用这个类时,会使用new 关键字,这时候jvm会帮我们构造一个该类的实例.这么做会比较耗费资源. 如果 ...

随机推荐

  1. codepen & js demos

    codepen & js demos Mutation Observer & customize resize event listener & demo https://co ...

  2. fiddler启动报错Unable to bind to port [8888],ErrorCode:10106

    启动运行fiddler 报错,提示Unable to bind to port [8888],ErrorCode:10106 解决方式: 使用Fiddler或其他类似的监听工具出现这种错误时, Una ...

  3. 51nod 1624 取余最短路(set)

    题意: 佳佳有一个n*m的带权矩阵,她想从(1,1)出发走到(n,m)且只能往右往下移动,她能得到的娱乐值为所经过的位置的权的总和. 有一天,她被下了恶毒的诅咒,这个诅咒的作用是将她的娱乐值变为对p取 ...

  4. 【MVVM Dev】多个具有依赖性质的ComboBox对数据的过滤

    一.前言 在界面编程中,我们常常会遇到具有依赖性质的ComboBox框,比如最常见的: 省/直辖市 => 地级市/区 => 区/街道 今天就说一下在WPF的MVVM模式中如何实现该功能 二 ...

  5. Redis的Sorted Set有序集合命令

    Sorted Set是Set的一个升级版本,它在Set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序.可以理解为有两列的mysql表, ...

  6. tomcat7.x远程命令执行(CVE-2017-12615)漏洞漏洞复现

    tomcat7.x远程命令执行(CVE-2017-12615)漏洞漏洞复现 一.漏洞前言 2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017 ...

  7. LOJ #6036.「雅礼集训 2017 Day4」编码 Trie树上2-sat

    记得之前做过几道2-sat裸体,以及几道2-sat前缀优化建图,这道题使用了前缀树上前缀树优化建图.我们暴力建图肯定是n^2级别的,那么我们要是想让边数少点,就得使用一些骚操作.我们观察我们的限制条件 ...

  8. 使图片水平并垂直居中的一个Hack

    淘宝的一个前端面试题:使用纯CSS实现未知尺寸的图片(但高宽都小于200px)在200px的正方形容器中水平和垂直居中. 想起了vertical-align:middle;但是不行,后来才知道还要di ...

  9. eclipse show view失效的解决办法

    今天打开eclipse,发现console窗口没有了,然后使用show view也无法打开,上网查找办法,找到了方法试了一下,窗口重置(Windows-->Perspective-->Re ...

  10. Windows服务器下用IIS Rewrite组件为IIS设置伪静态方法

      1.将下载的IIS Rewrite 组件解压,放到适当的目录(如 C:Rewrite)下,IIS Rewrite 组件下载 http://www.helicontech.com/download- ...