python 中单例模式

1、什么是单例模式:

  单例模式是指一个类有且只有一个实例对象,创建一个实例对象后,再创建实例是返回上一次的对象引用。(简单的讲就是两个实例对象的ID相同,节省了内存空间)

2、单例模式的创建: 

  举例创建一个类,比如宇宙只有一个地球,帮助理解单例模式

class Earth:
    pass
a=Earth()
print(a)
b=Earth()
print(b)
*****结果******
32096552
32096496
我们可以看出两个实例内存ID不相同,该类不是一个单例模式

  那么怎么能够让类只创建一个实例,而后再创建的实例是返回上一次的对象的引用呢?

  我们了解到,python中,一个类创建对象实例是通过调用父类object的 __new__(cls)方法来创建对象的

  我们可以通过重写 __new__(cls)方法去实现类只创建一个实例:

class Earth(object):
    __instance=None
    def __new__(cls):
        if cls.__instance==None:#如果__instance为空证明第一次创建实例
             cls.__instance=object.__new__(cls)
             return cls.__instance
        else:
            #如果不是第一次创建实例,返回上一次的对象引用
             return cls.__instance  
a=Earth()
print(id(a))
b=Earth()
print(b)
******结果*****
1730389200
1730389200

  上面例子我们通过__new__方法创建了一个单例模式类,但是该单例类再使用多线程是会存在一定问题。我们需要加入互斥锁的方式解决该问题。

import threading
class Earth(object):
    _instance_lock=threading.Lock()
    def __init__(self):
         pass
    def __new__(cls,*args,**kwargs):
        if not hasattr(Earth,'_instance'):
            with Earth._instance_lock:
                 if not hasattr(Earth,'_instance'):
                      Earth._instance=object.__new__(cls)
        return Earth._instance
a=Earth()
b=Earth()
print(a,b)
def task(arg):
    obj=Earth()
    print(obj)
for i in range(10):
    t=threading.Thread(target=task,args=[i,])
    t.start()
*****结果*****
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>
<__main__.Singleton object at 0x00000000029D06A0>

3、创建单例的其他方法:1、使用模块、2使用装饰器 3、使用类的方式4、基于metaclass方式

具体参考博客:https://www.cnblogs.com/huchong/p/8244279.html

猜你喜欢

转载自www.cnblogs.com/dushangguzhousuoli/p/11027994.html
今日推荐