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 _______________________________________________ BangPypers mailing list BangPypers@python.org https://mail.python.org/mailman/listinfo/bangpypers