flying sheep
flying sheep

Reputation: 8942

Invalidating a `functools.cached_property`’s cache

I’m using functools.cached_property to store a long-lived session object like this:

class Client:
    @cached_property
    def session(self):
        return service.login(...)

I want to invalidate the cache only in a very specific case, without giving up the convenience and clarity of cached_property. How can I achieve that?

Upvotes: 3

Views: 1430

Answers (1)

flying sheep
flying sheep

Reputation: 8942

functools.cached_property uses the same place where a regular instance attribute (self.attr = ...) would be stored: The object’s .__dict__! An invalidation method for your case would therefore look like:

class Client:
    @cached_property
    def session(self):
        return service.login(...)

    def logout(self):
        self.__dict__.pop('session', None)

If you want to invalidate all cached_propertys an object has, you can do this:

def invalidate_cached_properties(obj):
    cls = type(obj)
    cached = {
        attr
        for attr in list(self.__dict__.keys())
        if (descriptor := getattr(cls, attr, None))
        if isinstance(descriptor, cached_property)
    }
    for attr in cached:
        del obj.__dict__[attr]

Upvotes: 3

Related Questions