Redis auto search for python objects

I'm trying to implement classes for which Redis actually holds attributes, but the user of the class is unaware of this (ie. Persistence of objects across multiple clients). I know there are several libraries that port redis to python, but nobody does it just that easily (but please correct me if I'm wrong!)

I have successfully implemented automatic attribute re-storage, but I cannot get the search to work with __getattribute__

without infinite recursion. I think I'm trying to use object.__getattribute__

etc, but obviously I must be missing something:

class redisStored(object):
    global redis

    # A class method to implement object retrieval from redis
    # Call <Classname>.load(<id>) to create a new instance which exists in redis
    @classmethod
    def load(cls,id):
        # Create the object
        obj = cls.__new__(cls)
        # Set id without calling obj __setattr__
        object.__setattr__(obj,'id',int(id))
        # Return the object we created
        return obj

    def __str__(self):
        # Return "<ClassName>:<id>" to differentiate ids in redis
        # You can use this to say redis.hgetall(g) where g is the instance

        return "%s:%s" % (self.__class__.__name__, str(object.__getattribute__(self,'id')))
        #                                     self.id here ^ would cause infinite recursion

    # This works fine
    def __setattr__(self,name,value):
        redis.hset(self,name,value)
        return object.__setattr__(self,name,value)

    # This blows up with infinite recursion, WHY??
    def __getattribute__(self,name):
        _val = redis.hget(self,name)
        if not _val:
            return object.__getattribute__(self,name)
        else:
            return _val

      

If I trace this, it explodes inside _val = redis.hget(self,name)

, but I can't figure out why. Thanks for any help!

+3


source to share


1 answer


You have to be very careful when overloading __getattribute__

.

A side effect is that access self.__class__

calls __getattribute__

and creates a bogus redis request.

Since you are using new-style classes, you can use __getattr__

instead and avoid the infinite recursion problem, although if you use __getattr__

, you will return the object's attribute prior to redrawing the value if that attribute already exists in your instance.



Anyway, your object is immutable as long as you overload the method __setattribute__

, so this is not a big problem.

Please refer to this SO answer for more detailed difference between __getattr__

and __getattribute__

: Difference between __getattr__ vs __getattribute__

+2


source







All Articles