If as according to the docs, there is no guarantee of __del__ being called, anything that relies on that seems unsafe (depending on how robust one needs the solutions to be). Solutions I've seen elsewhere suggest creating something like a *release()* method on your objects and calling it explicitly before calling *del my_obj *(if you even call del, rather than just relying on GC).
Alternatively, if it suits the scenario, use a context manager. All suggestions lifted from (a SO that informed me in the past): http://stackoverflow.com/questions/6104535/i-dont-understand-this-python-del-behaviour On Mon, Feb 24, 2014 at 6:24 PM, Alex Martelli <al...@google.com> wrote: > Off the cuff, I'd make saveme into a function, not a class; > the saveme function would alter the class passed in as its only argument > (saving __init__ and/or __del__ methods it may have and replacing them with > other -- nested -- functions that call them and do the rest of the job) and > return the same class object it received. > > No time to actually write the code but this seems a much sounder > architecture. > > > Alex > > > > On Mon, Feb 24, 2014 at 4:49 PM, Sangeeth Saravanaraj < > sangeeth.saravana...@gmail.com> wrote: > >> This question was initially asked in tu...@python.org; Now I am widening >> the audience to gain attention. >> >> I want to create a decorator which should do the following things: >> => When an object of the decorated class is created, the objects name >> (say the value of the incoming "id" argument) should be stored as a record >> in a table in a database. >> => When an object of the decorated class is deleted, the record with >> this deleted objects name (i.e. object.id) should be removed from the >> table. >> >> Now, for example - consider the following snippet: >> >> @saveme >> class A(object): >> def __init__(self, id): >> self.id = id >> >> @saveme >> class B(object): >> def __init__(self, id): >> self.id = id >> >> "saveme" should do what I have explained earlier. >> >> a1 = A("A1") >> a2 = A("A2") >> a3 = A("A3") >> b1 = B("B1") >> b2 = B("B2") >> >> At this point if I query and print all the records in a table, I should >> get the following output: >> ["A1", "A2", "A3", "B1", "B2"] >> >> del a1 >> del a2 >> del a3 >> del b1 >> del b2 >> >> At this point, all entries in the table should be deleted; query should >> return an empty list! >> >> And, I want to highlight that the classes that are being decorated with >> "saveme" can de derived classes too [which initialises its base classes >> using super() method]! >> >> Now the following is what I have tried: >> >> class saveme(object): >> def __init__(self, klass): >> print "saveme::__init__()" >> self._klass = klass >> >> def __call__(self, *args, **kwargs): >> print "saveme::__call__()" >> obj = self._klass(*args, **kwargs) >> # creation of DB record will happen here! >> # i.e. something like add_to_db(kwargs.get("id")) >> return obj >> >> def __del__(self): >> # deletion of DB record will happen here! >> # i.e. something like remove_from_db(id) >> # TODO: how to retrieve the "id" here?! >> print "saveme::__del__()" >> >> >> class Parent1(object): >> def __init__(self): >> print "Parent1:: __init__()" >> super(Parent1, self).__init__() >> >> >> class Parent2(object): >> def __init__(self): >> print "Parent2:: __init__()" >> super(Parent2, self).__init__() >> >> >> @saveme >> class A(Parent1, Parent2): >> def __init__(self, id): >> print "A::__init__()" >> self.id = id >> #super(A, self).__init__() >> >> >> #@saveme >> #class B(object): >> # def __init__(self, id): >> # print "B::__init__()" >> # self.id = id >> >> >> def main(): >> a1 = A(id="A1") >> # b1 = B(id="B1") >> >> if __name__ == "__main__": >> main() >> >> >> When executed the above, I ran in to the following: >> >> saveme::__init__() >> saveme::__call__() >> A::__init__() >> Traceback (most recent call last): >> File "1.py", line 54, in <module> >> main() >> File "1.py", line 50, in main >> a1 = A(id="A1") >> File "1.py", line 10, in __call__ >> obj = self._klass(*args, **kwargs) >> File "1.py", line 39, in __init__ >> super(A, self).__init__() >> TypeError: must be type, not saveme >> saveme::__del__() >> >> >> When I commented "super(A, self).__init__()" in the class A :: __init__() >> method, it returned an object of type A and I was able to see the prints in >> the __call__ and __del__ methods but the __init__() methods of the base >> classes (Parent1 & Parent2) were not called! >> >> From the error message, what I could understand is - the object returned >> by saveme::__call__() is not of type A but of type saveme. But when I put a >> print in the saveme::__call__() I could see it returns an object of type A >> and not saveme. >> >> Now the question is - with this approach to capture the initiation and >> deletion events of an object, how do I initialise the base classes using >> super()? >> >> Or, is there any other better way to capture the __call__ and __del__ >> events for an object of a certain class - if so, how?! >> >> Thank you, >> >> Sangeeth >> >> >> PS: >> http://stackoverflow.com/questions/21826854/typeerror-when-using-super-method-with-class-decorator-for-a-derived-class >> >> >> _______________________________________________ >> Baypiggies mailing list >> baypigg...@python.org >> To change your subscription options or unsubscribe: >> https://mail.python.org/mailman/listinfo/baypiggies >> > > > _______________________________________________ > Baypiggies mailing list > baypigg...@python.org > To change your subscription options or unsubscribe: > https://mail.python.org/mailman/listinfo/baypiggies >
-- https://mail.python.org/mailman/listinfo/python-list