zoukankan      html  css  js  c++  java
  • 【python深入】单例模式

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

    比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 Config 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 Config 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 Config 这样的类,我们希望在程序运行期间只存在一个实例对象,而且在我们目前的程序中也确实是通过单例来实现的这个功能,是通过__new__的方式来实现的。

    然后是对单例模式的一个实现和验证:

    单例模式的实现可以有多种形式:

    ·使用模块

    ·使用__new__

    ·使用装饰器(decorator)

    ·使用元类 —— 后面看元类的内容

    (1)直接使用模块实现:

    可以新创建一个文件testdanlimoshibymokuai.py,例如:

    #coding=utf-8

    class my_Singleton(object):

        def foo(self):

            print '111'

       

    mysingleton = my_Singleton()

    之后在另外一个文件中进行调用,如下:

     

    可以看到结果:

     

    (2)使用__new__实现:

    class Singleton(object):

        def __new__(cls, *args, **kw):

            if not hasattr(cls, '_instance'):

                cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)

            return cls._instance

       

    class notSingleton(object):

        def __init__(self):

            pass

    结果验证:

    if __name__ == "__main__":

        #下面是单例的情况

        a1 = Singleton()

        a2 = Singleton()

        print id(a1)

        print id(a2)

       

        #下面是非单例的情况

        a4 = notSingleton()

        a5 = notSingleton()

        print id(a4)

        print id(a5)

    结果为:

     

    关于上面实现中具体用到的id()和hasattr(),具体含义如下:

    使用装饰器:

    #用装饰器实现的单例

    def Singleton2(cls):

        instances = {}

        @wraps(cls)

        def wrapper(*args, **kw):

            if cls not in instances:

                instances[cls] = cls(*args, **kw)

            return instances.get(cls, None)

        return wrapper

    @Singleton2

    class testClass(object):

        def __init__(self):

            self.value = 1

    验证结果:

     

    得到的结果是:

     

    备注:为什么是__new__,__new__的作用是什么?和__init__的区别是什么?还有看到__call__的,这个又是用来做什么的?

    另外,__双划线,和_单划线的这种,有什么区别?

    下面是关于以上几个问题的答案:

    1、__new__代表的含义是:在新式类中,才有__new__,这个其实才是构造函数,创建实例,返回类的实例对象,__init__则进行参数等的设置和丰富,就是当对象被创建初始化的时候使用的

    class Test1(object):

        def __init__(self):

            self.value = 1

    class Test2(object):

        def __new__(self, *args, **kwargs):

            return object.__new__(Other, *args, **kwargs)

       

        def __init__(self):

            self.value = 1

           

    class Other(object):

        pass

    打印type来确定一下:

    t1 = Test1()

    print type(t1)

       

    t2 = Test2()

    print type(t2)

    可以看到结果如下:

     

    其实是因为在Test2中__new__进行了重载,这里返回的是Other类的实例对象,那么Other类本身

    如果我们想要查看设置的value值,则可以通过下方代码:

        t1 = Test1()

        print type(t1)

        print t1.value

       

        t2 = Test2()

        print type(t2)

        print t2.value

    结果如下:

    修改成下面这样的形式:

     

    再执行语句就可以得到这个结果:

    后面需要再了解一下:如何给类设置属性、增加属性、删除属性。。。。。

    2、关于__xxx__、_xxx 和 __xxx的不同之处在于:参考文章:http://blog.csdn.net/li_101357/article/details/52794164

    首先给出各自含义,然后再结合实际例子进行理解:

    __xxx__:代表系统定义名字

    _xxx:保护变量,

    __xxx:类中的私有变量名

    参考文章:http://python.jobbole.com/87294/

  • 相关阅读:
    mysql 远程登陆不上
    hdu 5339 Untitled【搜索】
    SqlServer 书目
    passwordauthentication yes
    oracle 11g RAC ocfs2
    Oracle 11g RAC database on ASM, ACFS or OCFS2
    CentOS ips bonding
    Oracle 11g RAC features
    openStack 王者归来之 trivial matters
    openstack windows 2008 img
  • 原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/8619475.html
Copyright © 2011-2022 走看看