上次我们简单了解了一下什么是单例模式,今天我们继续探究。
上次的内容点这 python设计模式之单例模式(一)

上次们讨论的是GoF的单例设计模式,该模式是指:一个类有且只有一个对象。通常我们需要的是让实例共享一个相同的装态 比如数据库连接。Alex Martelli的建议的是开发人员应该关注状态和行为,而不是同一性,因此它也被称为Monostate(单态)模式。

Monostate单例模式的概念

先说说 MonoState 这个单词的意思,设计模式的名字都是很有意思的,因为为了方便交流、记忆,所以设计模式的命名都对 该模式的意图进行了表述。 Mono 是一个词根,英语中 Mono,Mon 都表示的是 1 的意思, state 意思为 " 状态 " 。 MonoState 的意思就是 " 单一的状态 ",MonoState 并不限制创建对象的个数,但是它的状态却只有一个状态

Monostate单例模式的使用

我们知道在python中,__dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值。所以下面我们可以使用dict来存储一个类所有对象的状态。来看下面这个例子:

class useDict:
    __state={"name":"cxa"}
    def __init__(self):
        self.age=27
        self.__dict__=self.__state
m=useDict()
m1=useDict()
m.age=23
print(m)
print(m1)
print(m.__dict__)
print(m1.__dict__)

运行以后输出结果。

<__builtin__.useDict instance at 0x7f78ceacc098>
<__builtin__.useDict instance at 0x7f78ceacc128>
{'age': 23, 'name': 'cxa'}
{'age': 23, 'name': 'cxa'}

首先我们看结果 我们发现每次对useDict实例化都会创建一个新的对象,然后我们通过m修改了age属性的值后,m1的age属性值也发生了变化。
除此之外我们还可以使用__new__方法本身来实现。

class useNew(object):
    _state={}
    def __new__(cls,*args,**kwargs):
        obj=super(useNew,cls).__new__(cls,*args,**kwargs)
        obj.__dict__=cls._state
        return obj
a=useNew()
a1=useNew()
a.x=3
print(a)
print(a1)
print(a.__dict__)
print(a1.__dict__)

下面是输出结果

<useNew object at 0x7f78ceb873d0>
<useNew object at 0x7f78ceb87b50>
{'x': 3}
{'x': 3}

两种写法的效果是一样的。

元类的实现方式

元类是一个类的类,这就意味着该类是它的元类的实例。对于已经存在的类来说,当需要创建对象的时候,将调用python的特殊方法__call__,我们可以通过使用元类的__call__方法,来控制一个对象的实例化,具体看下面的例子
一个数据库连接的例子

import pymysql
class MetaSingleton(type):
    _inst={}
    def __call__(cls,*args,**kwargs):
        if cls not in cls._inst:
            cls._inst[cls]=super(MetaSingleton,cls).__call__(*args,**kwargs)
        return cls._inst[cls] class MysqlDb(metaclass=MetaSingleton):
     connection=None
     def conn(self):
        if self.connection is None:
             self.connection= pymysql.connect(host='127.0.0.1', port=3306, user='root',
             passwd='Aa1234', db='user', charset='utf8mb4')
             self.cursor=self.connection.cursor()
        return  self.cursor
d1=MysqlDb().conn()
d2=MysqlDb().conn()

单例模式的缺点

介绍了这么长时间的单例模式,也许你会有疑问,那单例模式有什么缺点呢?
虽然单例模式的效果很好但是依然存在一些问题,因为单例具有全局访问权限,所以可能出现以下问题:

  • 全局变量可能在某个地方被改了但是不知道。(比如之前的那个使用__dict__的例子)。
  • 可能会对同一个对象创建多个引用。由于单例只创建一个对象,因此这种情况下会对一个对象创建对个引用。
  • 所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。

到此为止,我们就把单例模式的相关内容介绍完了,后续也许会写关于其他设计模式的相关文章,如果你喜欢的话,转发到朋友圈和小伙儿们一起分享吧。

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

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

    前言 单例模式是创建模式中比较常见和常用的模式,在程序执行的整个生命周期只存在一个实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python ...

  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. BZOJ 2333 棘手的操作(离线+线段树+带权并查集)

    这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...

  2. 用select模拟一个socket server成型版

    1.你往output里面放什么,下次循环就出什么.  2. 1.服务器端:实现了收和发的分开进行 import select,socket,queue server=socket.socket() s ...

  3. 通过logger命令记录日志

    通过logger命令记录日志 logger是一个shell命令接口,可以通过该接口使用Syslog的系统日志模块,还可以从命令行直接向系统日志文件写入一行信息. ------------------- ...

  4. POJ1474:Video Surveillance——题解

    http://poj.org/problem?id=1474 题目大意:给按照顺时针序的多边形顶点,问其是否有内核. —————————————————————————————— (和上道题目一模一样 ...

  5. POJ1741:Tree——题解+树分治简要讲解

    http://poj.org/problem?id=1741 题目大意:给一棵树,求点对间距离<=k的个数. ———————————————————— 以这道题为例记录一下对于树分治的理解. 树 ...

  6. CF25E:Test——题解

    https://vjudge.net/problem/CodeForces-25E 题目大意:给三个字符串,求最小串,使得前三个串都是它的子串. ———————————————— 这题虽然是看哈希的时 ...

  7. Consul入门

    推荐: Consul 原理和使用简介 启动:consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node Litao-Mac ...

  8. BZOJ1509 NOI2003 逃学的小孩

    Description: Input: 第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的信息.第i+1行包含整数Ui.Vi.Ti(1 ...

  9. eclipse的最新版本luna的中建立svn和maven

    http://blog.csdn.net/notillusion/article/details/40950185

  10. HTML学习基本代码

    HTML的代码比较繁琐,在此记下一些基本的东西,以后自己回来看看 <html> <head> <title>我的人生啊</title> <styl ...