[Tutor] Object destruction

Peter Otten __peter__ at web.de
Sun May 29 12:02:30 EDT 2022


On 24/05/2022 15:27, Dimitar Ivanov wrote:
> Hi all,

Hi Dimitar!

>
> I'm trying to come up with a (working) design of tracking an object
> throughout its lifecycle but I'm unable to find quite what I'm looking for,
> so I hope you folks will be able to give me some tips.
>
> I have an object that is being created and I want to "trace" that object in
> a separate static class that other threads and objects will be able to
> access if necessary:
>
> class TestClass:
>
>      def __init__(self, name):
>          self.name = name
>          self._finalizer = weakref.finalize(self, self.finalize)

A bound method keeps a reference to an instance of the class. Therefore
this instance is never garbage-collected unless the method object is
released. In your case this method object is kept alive until the
instance is released...

>
>      def do_stuff(self):
>          print(f"Object {self.name} doing stuff")
>          Tracer.trace(self.name)
>          time.sleep(5)
>
>      def finalize(self):
>          print(f"Entered finalize method for object {self.name}")
>          Tracer.untrace(self.name)


An easy fix would be to turn the finalize() method into a function:

def finalize(name):
     print("finalizing", name)
     Tracer.untrace(name)


class TestClass:

     def __init__(self, name):
         self.name = name
         self._finalizer = weakref.finalize(self, lambda: finalize(name))

     def do_stuff(self):
         print(f"Object {self.name} doing stuff")
         Tracer.trace(self.name)
         time.sleep(5)

> Here, I have the static object that "traces" those objects:
>
> class Tracer:
>
>      traced_objects = []
>
>      @staticmethod
>      def trace(some_object):
>          Tracer.traced_objects.append(some_object)
>
>      @staticmethod
>      def untrace(some_object):
>          Tracer.traced_objects.remove(some_object)
>
> And here's my main method where I test creating the objects, kicking off
> their do_stuff methods in a thread and then deleting them and checking if
> they've been removed from the traced_objects list in the Tracer class:
>
> if __name__ == '__main__':
>      objectOne = TestClass("Object1")
>      objectTwo = TestClass("Object2")
>      thrd1 = Thread(target=objectOne.do_stuff)
>      thrd2 = Thread(target=objectTwo.do_stuff)
>      thrd1.start()
>      thrd2.start()
>      thrd1.join()
>      thrd2.join()
>      del objectOne
>      del objectTwo
>      print("Threads are done, checking Tracer's dict")
>      print(f"Tracer's dict: {Tracer.traced_objects}")
>
> It seems like the Finalizer is only kicking off the objects' finalize
> methods once the program exits, which, if I'm reading the documentation
> right, is the correct behaviour; however, I need that finalize method
> kicked off as soon as any reference to those objects is removed. Can I
> achieve that in any way?
>
> Thanks a lot in advance and please, do let me know if my explanation is
> vague and/or unclear!
>
> Regards,
> Dimitar
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



More information about the Tutor mailing list