1

Imagine that I have the following code (This is just an example for demonstrating the thing that I want to achieve):

class Foo:

    def __init__(self, name):
        self.name = name

    def update_something(self, number):
        """
        This method is responsible for updating the object state, and it will be called hundreds of times at the same time
        So updating its state last call will be enough.
        """
        if number != 100:
            print(f"This method has been called for: ({number}) of times ---> [{self.name}]")
        else:
            print(f"This is the Final call ---> [{self.name}]")


if __name__ == '__main__':
    obj1 = Foo("obj1")
    obj2 = Foo("obj2")
    obj3 = Foo("obj3")
    obj4 = Foo("obj4")
    #  .
    #  .
    #  .
    # I have many objects
    list_of_objects = [obj1, obj2, obj3, obj4]

    # for example Let's imagine we have the following code
    for i in range(100):
        print("---")
        for obj in list_of_objects:
            obj.update_something(i)

The results for sure will be:

This method has been called for: (0) of times ---> [obj1]
This method has been called for: (0) of times ---> [obj2]
This method has been called for: (0) of times ---> [obj3]
This method has been called for: (0) of times ---> [obj4]
...
This method has been called for: (100) of times AND This is the Final call ---> [obj1]
This method has been called for: (100) of times AND This is the Final call ---> [obj2]
This method has been called for: (100) of times AND This is the Final call ---> [obj3]
This method has been called for: (100) of times AND This is the Final call ---> [obj4]

Instead, since it is performance-consuming, I want to take the last call in that "chain". so the update method will be called only once if they are repeatedly calling in a very very short time.

This is the Final call ---> [obj1]
This is the Final call ---> [obj2]
This is the Final call ---> [obj3]
This is the Final call ---> [obj4]
Uncle Bob
  • 155
  • 8
  • 1
    The type of monitoring you want should be done by the *caller*, not the method itself. – chepner Jan 24 '23 at 15:49
  • It's not really clear what you are trying to achieve? Do you want the update to be only called once? Then why call it 100 times? Or do you want the message to only be displayed once? Then just remove whatever happens `if number != 100` – matszwecja Jan 24 '23 at 15:50
  • @matszwecja If I understand, the OP is looking for what in javascript terms I would call a debouncer. – JonSG Jan 24 '23 at 15:53
  • I wouldn't even bother with a test. Use two sets of calls: one, under `for i in range(99)`, the second *after* the loop with `for obj in list_of_objects: print("Final call"); obj.update_something(100)`. – chepner Jan 24 '23 at 15:53
  • Check out : https://gist.github.com/walkermatt/2871026 and see if that is in-line with what you are loking for – JonSG Jan 24 '23 at 15:54
  • 1
    @JonSG, This is exactly what I was looking for, Thank you. Please post your answer so I can accept it – Uncle Bob Jan 24 '23 at 16:05
  • 1
    @UncleBob if that seems to work, here is a StackOverflow question that also references that gist. I propose to close this as a duplicate, though an interesting one and I will personally use this code in the future. https://stackoverflow.com/questions/61476962/python-decorator-for-debouncing-including-function-arguments Be sure to read the comments on that gist as there are lots of good additional implementation details – JonSG Jan 24 '23 at 16:08

0 Answers0