python 单例模式,造成子类在继承时,会直接指向单例,被继承类中的方法失效

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类。

上面两种方法需要根据实际需求来选择。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值