单例设计模式:
单例模式提供的机制:确保类有且只有一个特定类型的对象,并提供全局访问点。
特性:
1.确保类有且只有一个对象被创建
2.为对象提供一个访问点,以使程序可以全局访问该对象
3.控制共享资源的并行访问。
解决了什么问题:
避免了同一资源产生相互冲突的请求。(用于日志记录,数据库操作,打印机后台处理程序)
优缺点:
1.优点:
1.1 减少资源的过度使用如在:线程池、缓存、对话框、注册表等
2.缺点:
2.1全局变量可能在某处已经被误改。
2.2同一个对象可能创建多个引用。
2.3依赖于全局变量的类都会耦合成全局数据,耦合度增加。
1.理解单例模式原理
# 使用单例模式创建类
class Singleton(object):
# 创建新类前,先调用__new__
def __new__(cls):
# hasattr :判断是否有instance属性,
# if 没有就创建,if 有就直接返回
if not hasattr(cls,"instance"):
cls.instance = super(Singleton,cls).__new__(cls)
# print(cls.instance)
return cls.instance
# 未使用单例模式创建类
class Singleton2(object):
pass
# 用单例模式创建两个类
s0 = Singleton()
print ("Object created", s0)
s1 = Singleton()
print ("Object created", s1)
# 用非单例模式创建两个类
s2 = Singleton2()
print ("Object created", s2)
s3 = Singleton2()
print ("Object created", s3)
我们来看看输出结果的差异:
('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton2 object at 0x02598270>)
('Object created', <__main__.Singleton2 object at 0x02598290>)
2.单例模式的懒汉式
特性:保证了需要使用的时候才创建对象。(防止导入模块,但没有使用,造成的浪费)
class Singleton:
__instance = None
def __init__(self):
if not Singleton.__instance:
print ("__init__ method called..")
else:
print ("Instance already created:",self.getInstance())
@classmethod
def getInstance(cls):
if not cls.__instance:
cls.__instance = Singleton()
return cls.__instance
s = Singleton() # 初始化,但不创建
print("Object created", Singleton.getInstance())# 使用的时候创建
s1 = Singleton()
3.Monostate单例模式
单态单例模式:所有对象共享相同状态。(关心的是状态和行为,而不是同一性)
class Borg:
__shared_state = {"1":"2"}
def __init__(self):
self.x = 1
self.__dict__ = self.__shared_state
pass
b = Borg()
b1 = Borg()
b.x = 4
print ("Borg Object 'b': ",b) # b和b1不是同一个对象
print ("Borg Object 'b1': ",b1)
print ("Borg State 'b': ",b.__dict__) # b和b1共享状态
print ("Borg State 'b1': ",b1.__dict__)
4.单例和元类
元类概念:元类是类的类。(a = 5 ,type(a) 为 int ,type(int) 为 type)
元类的按例:
class MyInt(type):
def __call__(cls, *args, **kwds):
print ("**** Here is My int ****",args)
print ("Now do whatever you want with these objecys...")
return type.__call__(cls, *args, **kwds)
class int(metaclass = MyInt):
def __init__(self, x, y):
self.x = x
self.y = y
i = int(4,5)
元类的单例模式:
class MetaSingleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(MetaSingleton,cls).__call__(*args,**kwargs)
return cls._instances[cls]
class Logger(metaclass = MetaSingleton):
pass
logger1 = Logger()
logger2 = Logger()
print (logger1,logger2)
5.单例模式I
场景:多个web应用共享一个数据库,为了避免数据库操作冲突,采用单例模式
import sqlite3
class MetaSingleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls.instances:
cls._instances[cls] = super(MetaSingleton,cls).__call__(*args,**kwargs)
return cls._instances[cls]
class Database(metaclass = MetaSingleton):
connection = None
def connect(self):
if self.connection is None:
self.connection = sqlite3.connect("db.sqlite3")
self.cursorobj = self.connection.cursor()
return self.cursorobj
db1 = Database.connect()
db2 = Database.connect()
print ("Datebase Objects DB1", db1)
print ("Datebase Objects DB2", db2)
6.单例模式II
场景:运行状况监控服务。我们对监控对象的操作肯定是同一个,所以用单例模式实现。
class HealthCheck:
_instance = None
def __new__(cls, *args, **kwargs):
if not HealthCheck._instance:
HealthCheck._instance = super(HealthCheck,cls).__new__(cls,*args,**kwargs)
return HealthCheck._instance
def __init__(self):
self._servers = []
def addServer(self):
self._servers.append("Server 1")
self._servers.append("Server 2")
self._servers.append("Server 3")
self._servers.append("Server 4")
def changeServer(self):
self._servers.pop()
self._servers.append("Server 5")
hc1 = HealthCheck()
hc2 = HealthCheck()
hc1.addServer()
print ("Schedule health check for server (1)..")
for i in range(4):
print ("Checking ",hc1._servers[i])
hc2.changeServer()
print ("Schedule health check for server (2)..")
for i in range(4):
print ("Checking ",hc2._servers[i])
生产消费设计模式:
对于Queue,在多线程通信之间扮演重要的角色
添加数据到队列中,使用put()方法
从队列中取数据,使用get()方法
判断队列中是否还有数据,使用qsize()方法
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行解耦。
from threading import Thread
import queue
importtime
q = queue.Queue() # 创建一个队列容器,用来保存生产者产生的数据
classProducer(Thread):
"""生产者线程"""
def run(self):
count = 0
while True:
if q.qsize() < 50:
for i in range(3):
count += 1
msg = "产品 %d" % count
q.put(msg)
print("生产者%s 生产了一个数据 %s" % (self.name, msg))
time.sleep(1)
classCustomer(Thread):
"""消费者线程"""
def run(self):
while True:
if q.qsize() > 20:
for i in range(2):
msg = q.get()
print("消费者%s 消费了一个数据 %s" % (self.name, msg))
time.sleep(1)
fori in range(3):
p = Producer()
p.start()
fori in range(5):
c = Customer()
c.start()