前言

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

系列文章

目录

简单理解

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

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. delphi使用SQL的教程4(使用Params属性为参数赋值 )

    17.4.1 使用Params属性为参数赋值   TQuery部件具有一个Params属性,它们在设计时不可用,在程序运行过程中可用,并且是动态建立的,当为TQuery部件编写动态SQL 语句时, D ...

  2. Vue.js checkbox 练习

    <div id="app"> <input type=" />足球 <input type=" />篮球 <input ...

  3. DataTable Excel 导出:

    public static class CSVFileHelper { public static string ToHtmlTable(this DataTable target) { return ...

  4. UVA11625_Lines of Containers

    题意很简单,给你一个n*m的矩阵,现在问你这个矩阵能否变为标准矩阵(即数字从小到大),如果能最少需要几步呢? 其实是个赤果果的水题.记得暑假安叔也出过一个类似的题目,那个好像是在codeforces上 ...

  5. js function的方法名是一个变量 能被重复定义 当变量名一致时候 会使用最后一个function

  6. Django 2.0 学习(18):Django 缓存、信号和extra

    Django 缓存.信号和extra Django 缓存 由于Django是动态网站,所以每次请求均会去数据库进行相应的操作,当程序访问量大时,耗时必然会显著增加.最简单的解决方法是:使用缓存,缓存将 ...

  7. Class类是什么? Class.forName()是干什么的?

    Class类概念 Class类用来描述一个类的结构,比如描述一个类有哪些成员,有哪些方法等.有多种方法可以获取一个类对应的Class类实例,比如: //第一种方式获取描述Dog类结构的Class类实例 ...

  8. Bond UVA - 11354(并查集按秩合并)

    题意: 给你一张无向图,然后有若干组询问,让你输出a->b的最小瓶颈路. 解析: 应该都想过用prime的次小生成树做..但二维数组开不了那么大..所以只能用kruskal了.... #incl ...

  9. Native Wifi API

    原文链接地址:https://www.cnblogs.com/jackcin/p/3285357.html 在windows平台下,可以使用native wifi api来控制无线网卡,包括获取无线网 ...

  10. PHP 中的新语法 new static 是个啥意思?

    简单通俗的来说, self就是写在哪个类里面, 实际调用的就是这个类.所谓的后期静态绑定, static代表使用的这个类, 就是你在父类里写的static, 然后通过子类直接/间接用到了这个stati ...