假设我们在一个与数据库交互的系统中,需要进行数据库操作,那么我们就有必要了解单例模式,单例模式使得我们不用每次进行数据库的操作时都去链接数据库。
我将循环渐进,由浅入深的写一下单例模式示例。
实例1:
db.py
class Foo(object): def __init__(self): self.conn = "连接数据库" def get(self): return self.conn obj = Foo()
views.py
import db print(db.obj)
run.py
import db import views print(db.obj)
执行run.py,打印结果如下,这就是单例模式
<db.Foo object at 0x000001C1D8FC5A58> <db.Foo object at 0x000001C1D8FC5A58>
实例二:
注意这里使用了锁来解决线程安全问题
import threading import time class Foo(object): instance = None lock = threading.Lock() def __init__(self): self.a1 = 1 self.a2 = 2 import time import random time.sleep(2) @classmethod def get_instance(cls,*args,**kwargs): if not cls.instance: with cls.lock: if not cls.instance: obj = cls(*args,**kwargs) cls.instance = obj return cls.instance return cls.instance def task(): obj = Foo.get_instance() print(obj) import threading for i in range(5): t = threading.Thread(target=task,) t.start() time.sleep(10) Foo.get_instance()
实例三:
import threading class Foo(object): instance = None lock = threading.Lock() def __init__(self): self.a1 = 1 self.a2 = 2 import time time.sleep(2) def __new__(cls, *args, **kwargs): if not cls.instance: with cls.lock: if not cls.instance: obj = super(Foo, cls).__new__(cls, *args, **kwargs) cls.instance = obj return cls.instance return cls.instance def task(): obj = Foo() print(obj) import threading for i in range(5): t = threading.Thread(target=task, ) t.start()
实例四:
import threading lock = threading.Lock() class Singleton(type): def __call__(cls, *args, **kwargs): if not hasattr(cls, ‘instance‘): with lock: if not hasattr(cls, ‘instance‘): obj = cls.__new__(cls, *args, **kwargs) obj.__init__(*args, **kwargs) setattr(cls, ‘instance‘, obj) return getattr(cls, ‘instance‘) return getattr(cls, ‘instance‘) class Foo(object, metaclass=Singleton): def __init__(self): self.name = ‘alex‘ obj1 = Foo() obj2 = Foo() print(obj1, obj2)