我们在使用面向对象的方法开发过程中,每次都需要利用定义好的类去创建一个对象。但是每次创建一个新对象都要在内存里开辟一块新的内存出来,代码和结果如下

class Foo(object):
    def __init__(self):
        self.name='wgw'
    def sayhi(self):
        return "I`m wgw"
#用定义好的类分别创建了3个对象
user1=Foo()
print 'I am user1',id(user1)
user2=Foo()
print 'I am user2',id(user2)
user3=Foo()
print 'I am user3',id(user3)
#打印出来的三个对象的内存地址,各不相同说面创建了不同内存空间
I am user1 39824520
I am user2 39824632
I am user3 39824688

如果有很多的对象要创造的话,那么对内存的开销就非常可观了。为了解决这个情况,单例模式就是比较适合的。所谓的单例模式,就是一个类只创建一个实例,当有多个实例需要创建的时候就调用第一个实例的内存地址返回给其他的实例。这样在实例化的过程中,只有占用了一份内存地址。看代码

class Foo(object):
    #需要定义一个静态字段来保存内存地址,默认是空的
    __instance = None
    def __init__(self):
        pass
    """
    先定义一个instance()方法
    通过类方法把Foo传递给cls
    这样调用instance()方法的时候就不需要创建实例
    """
    @classmethod
    def instance(cls):
        #先检查静态字段里是否保存了内存地址,如果有保存
        if cls.__instance:
            #就把内存地址返回给实例化对象
            return cls.__instance
        #如果没保存
        else:
            """
            就先用Foo类的内存地址给静态字段赋值
            最后把静态字段的内存地址返回给对象
            """
            cls.__instance=Foo
            return cls.__instance
"""
这里就不是通过传统的obj=Foo()的方法来实例化了
而是通过Foo.instance()这个定义的类方法来实例化对象
如果__instance字段有值,就把__instance的内存地址返给obj
如果没有值就相当于obj=Foo()  然后把实例化之后的内存地址保存
到__instance()中,供其他实例使用
"""
user1=Foo.instance()
print 'I am user1',id(user1)
user2=Foo.instance()
print 'I am user2',id(user2)
user3=Foo.instance()
print 'I am user3',id(user3)
#现在不管实例化多少个对象,都只调用一份内存地址了
I am user1 40073720
I am user2 40073720
I am user3 40073720

设计模式之单例模式_python 单例模式



单例模式的总结

单例模式有一下特点:
  1、单例类只能有一个实例。
  2、单例类必须自己自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免整出多头。

  正是由于这个特 点,单例对象通常作为程序中的存放配置信息的载体,因为它能保证其他对象读到一致的信息。例如在某个服务器程序中,该服务器的配置信息可能存放在数据库或 文件中,这些配置数据由某个单例对象统一读取,服务进程中的其他对象如果要获取这些配置信息,只需访问该单例对象即可。这种方式极大地简化了在复杂环境 下,尤其是多线程环境下的配置管理,但是随着应用场景的不同,也可能带来一些同步问题。