[Python] Python, update cached property when field of attribute changes

Discussão em 'Python' iniciado por Stack, Agosto 15, 2025.

  1. Stack

    Stack Membro Participativo

    I'll try to take a dummy example to explain my goal: updating a cache (defined with @cached_property) computed from an instance attribute.

    Let's say I have an object AllCircles that is composed of a tuple of Circles. Each Circle is defined with its radius. I want to cache the value of the biggest radius as a property of AllCircles. Here's what I did:

    from functools import cached_property

    class Circle():
    def __init__(self, radius: float):
    self.radius = radius

    class AllCircles():
    def __init__(self, circles: (Circle)):
    self._circles = tuple(circles)

    @property
    def circles(self):
    print("Call getter")
    return self._circles

    @circles.setter
    def circles(self, value):
    print("Call setter")
    self.__dict__.pop('max_radius', None)
    self._circles = value

    @cached_property
    def max_radius(self):
    print("Compute cached property radius")
    return max([_.radius for _ in self.circles])


    I can define an object AllCircles from a set of Circles, and call max_radius to get the biggest value.

    > my_circles = AllCircles([Circle(4), Circle(3)])
    > my_circles.max_radius
    Compute cached property radius
    Call getter
    4


    Which is ok. If I call the function again, I get:

    > my_circles.max_radius
    4


    as nothing's printed, I guess the cache is called, that's ok. If I set the circles:

    > my_circles.circles = [Circle(5), Circle(0)]
    > my_circles.max_radius
    Call setter
    Compute cached property radius
    Call getter
    5


    I again get the right value, because setting a new object circles calls the setter, and its self.__dict__.pop()method empties the cache.

    However, if I directly modify the radius of a circle, I don't empty my cache:

    > my_circles.circles[0].radius = 9
    > my_circles.max_radius
    Call getter
    5 # instead of 9


    How can I change my code to update my cache when an attribute is modified directly ?

    Continue reading...

Compartilhe esta Página