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/

  • 相关阅读:
    LRU
    c++ 在临时变量上使用const引用
    剑指 Offer 13. 机器人的运动范围
    C++之对象包含与成员函数不兼容的类型限定符
    C#獲取指定格式日期
    在ORACLE產生001,002的流水號
    ASP.NET中DataList数字分页代码
    生成條碼標的Class
    sql 将横的记录显示为竖的记录 max(case when CASE ltrim(ps.SIZE) WHEN '4.5' THEN ps.PairPerCarton END is null then null else ps.PairPerCarton end ) AS [4.5]
    为什么margin-top值不是作用域父元素
  • 原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/8619475.html
Copyright © 2011-2022 走看看