Python 实现Redis操作类的单例模式

Python实现单例模式的使用—-redis和logging

前几天刚学习了几个基本的设计模式,今天来实践下单例模式。

简单介绍一下单例模式:单例模式属于创建型模式,只能创建一个实例,而且只能存在一个实例,其他,其他对象调用该实例的话,也只能调用唯一的这个实例。

下面结合具体的例子来分析:

reids实现单例模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

class Redis_operation:
"""some operation about redis"""

_instance = {}

def __init__(self, redis_instance):
self._redis = redis_instance

@classmethod
def choice_redis_db(cls, db):
"""choice designated db in redis"""
"""different redis db , but follow the single mode"""
if not cls._instance.setdefault(db, None):
cls._instance[db] = get_redis_connection(db)
return cls(cls._instance[db])

def check_key_value(self, key, value):
"""compare key-value code and code in redis for equality """
try:
if self._redis.exists(key):
_value = self._redis.get(key).decode()
return True if _value == value else False
else:
return False
except Exception as e:
consumer_logger.error(e)
finally:
self._redis.close()

def save_key_value(self, key, code, time):
"""cache verification code for ten minutes"""
try:
self._redis.set(key, code)
self._redis.expire(key, time)
except Exception as e:
consumer_logger.error(e)
finally:
self._redis.close()

分析:

上述例子中所使用@classmethod装饰器来实现,@classmethod装饰器可以帮助你在实例化类之前做一些特殊的操作。上述的例子中,我在实例化类之前首先判断是否类属性_instance存在某个特定的redis实例,如果存在,那么我直接返回这个_instance,如果不存在,将使用将创建相应的redis实例,然后存放到_instance字典中,最后创建该类的实例。通常最后返回的就是该类的实例对象。

注:因为我考虑到不同的数据存放到不同的redis的db中,只采用了一个redis,单线程下是线程安全的。此时单例模式是有效的,而如果有多个服务器负载均衡请求到不同的redis中,此时就要考虑使用redis分布式锁了。

最后,之前我的文章中提到logging系统采用了抽象工厂设计模式,其实针对django不同app下的logger也可以采用单例模式,节省内存创建对象的资源消耗