class RedisBase:
__instance = None
__first_init = None
def __init__(self, ilog, eilog):
self._ilog = ilog
self._eilog = eilog
if not self.__first_init:
try:
# 连接池
self.client = StrictRedis(
host=config.db_config['redis'].get("redis_host"),
port=config.db_config['redis'].get("redis_port"),
password=config.db_config['redis'].get("redis_pwd"),
db=config.db_config['redis'].get("redis_dr_db")
)
self.__first_init = True
except Exception as e:
if self._eilog:
self._eilog.error("[REDIS] error: %s", e, exc_info=e)
else:
print("[REDIS] error: %s" % e)
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super(RedisBase, cls).__new__(cls)
return cls.__instance
class SynonymRedis(RedisBase):
def __init__(self, ilog, eilog):
super(SynonymRedis, self).__init__(ilog, eilog)
async def get_synonym_group_id(self, term):
return await self.client.get("None_syn_{}".format(term))
async def set_synonym_group_id(self, term, group_id):
await self.client.set("None_syn_{}".format(term), group_id)
async def get_synonym_group(self, group_id):
res = await self.client.smembers("None_syn_group_{}".format(group_id))
res = decoder(res)
return res
async def set_synonym_group(self, group_id, *terms):
await self.client.sadd("None_syn_group_{}".format(group_id), *terms)
async def list_synonyms(self):
for group in self.client.keys("None_syn_group_*"):
await self.client.smembers(group)
上面是定义的两个继承关系的类,下面是使用 SynonymRedis类进行操作
class Synonyms:
def __init__(self):
self._dynamic_source = SynonymRedis(info_log, error_log)
async def get_synonyms(self, term, include_self=True):
try:
group_id = await self._dynamic_source.get_synonym_group_id(term)
terms = await self._dynamic_source.get_synonym_group(group_id)
if not include_self:
terms.discard(term)
return terms
except Exception as e:
print(e)
执行到 group_id = await self._dynamic_source.get_synonym_group_id(term)时,发生错误:
AttributeError: 'RedisBase' object has no attribute 'get_synonym_group_id'
但是,上面代码明确可以看出SynonymRedis类里面有这个方法。
然后就发现这个错误提示的是RedisBase类没有这个方法,而不是SynonymRedis这个类没有方法。之后发现,在执行
self._dynamic_source = SynonymRedis(info_log, error_log)
这一句时,实际上实例化的不是SynonymRedis类,而是RedisBase类。
之后针对该点进行排查,发现RedisBase作为父类,被定义成了单例模式,且之前已经被实例化过,所以不允许再实例化SynonymRedis类。。。
针对该问题,有两种解决方法:
1-删除掉RedisBase类的单例模式限制;
2-全局化实例化一个SynonymRedis类。
上面两种方法需要根据实际需求来选择。