The python singleton mode causes subclasses to directly point to the singleton when inheriting, and the method in the inherited class becomes invalid

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)

The above is the class of the two inheritance relationships defined, and the following is the operation using the SynonymRedis class

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)

When executing group_id = await self._dynamic_source.get_synonym_group_id(term), an error occurs:

AttributeError: 'RedisBase' object has no attribute 'get_synonym_group_id'

However, the above code clearly shows that there is this method in the SynonymRedis class.

Then I found out that this error indicates that the RedisBase class does not have this method, not that the SynonymRedis class has no method. It was later found that when executing

When self._dynamic_source = SynonymRedis(info_log, error_log)
this sentence, it is not the SynonymRedis class that is actually instantiated, but the RedisBase class.

After investigation on this point, it was found that RedisBase, as the parent class, was defined as a singleton mode and had been instantiated before, so instantiation of the SynonymRedis class was not allowed. . .

For this problem, there are two solutions:

1- Delete the singleton mode restriction of the RedisBase class;

2- Instantiate a SynonymRedis class globally.

The above two methods need to be selected according to actual needs.

 

 

Guess you like

Origin blog.csdn.net/u010483897/article/details/103354241