0

I'm working with a redis database and I'd like to integrate my prototype code to my baseline as seamlessly as possible so I'm trying to bury most of the inner workings with the interface from the python client to the redis server code into a few base classes that I will subclass throughout my production code.

I'm wondering if the assignment operator in python = is a callable and whether if it possible to modify the callable's pre and post behavior, particularly the post behavior such that I can call object.save() so that the redis cache would be updated behind the scenes without having to explicitly call it.

For example,

# using the redis-om module
from redis_om import JsonModel

kwargs = {'attr1': 'someval1', 'attr2': 'someval2'}
jsonModel = JsonModel(**kwargs)

# as soon as assignment completes, redis database 
# has the new value updated without needing to 
# call jsonModel.save()
jsonModel.attr1 = 'newvalue' 

1 Answer 1

1

You can make such things with proxy class through __getattr__ and __setattr__ methods:

class ProxySaver:
    def __init__(self, model):
        self.__dict__['_model'] = model

    def __getattr__(self, attr):
        return getattr(self._model, attr)

    def __setattr__(self, attr, value):
        setattr(self._model, attr, value)
        self._model.save()

p = ProxySaver(jsonModel)
print(p.attr1)
p.attr1 = 'test'

But if attributes has a complex types (list, dict, objects, ... ), assignment for nested objects will not been detected and save call will be skipped (p.attr1.append('test'), p.attr1[0] = 'test2').

Sign up to request clarification or add additional context in comments.

4 Comments

Why would p.attr1 = [] not be detected? This would go through setattr afaik. I agree regarding the .append(). That will be missed. I wonder if its possible to detect changes/differences and then update those specific values.
@LeanMan Yes p.attr1 = [] would be detected, but p.attr1.append('test') and p.attr1[0]='test2' would not. I was fix ambiguity in my answer.
Thanks. Btw, do you know where the original implementation of setattr can be found? Its possible by overriding it we are introducing an unintended behavior. I found this SO that uses super().__setattr__(name, value) which might be the preferred way to do it. Not sure. stackoverflow.com/questions/17020115/…
So just realized this. The case for p.attr1[0]='test2' can be handled by __getitem__ dunder method. I can probably create my own set of set, dict and list for all these collections and override the different methods required for the desired behavior. But the only thing I haven't figured out is access to the document in redis. p doesn't have the .save() method, its owner does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.