<div dir="ltr"><div class="gmail_default" style="font-family:'courier new',monospace"><span style="font-family:arial">On Mon, Feb 24, 2014 at 10:53 PM, Peter Otten </span><span dir="ltr" style="font-family:arial"><<a href="mailto:__peter__@web.de" target="_blank">__peter__@web.de</a>></span><span style="font-family:arial"> wrote:</span><br>
</div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="">
Sangeeth Saravanaraj wrote:<br>
<br>
> I am trying to capture an object initiation and deletion events using the<br>
> __call__() and __del__() methods with the following approach.<br>
<br>
</div>Note that there is no guarantee that __dell__ will ever be called. Usually<br>
it is better to introduce a weakref with callback.<br>
<div><div class="h5"><br>
> class A(object):<br>
>     def __init__(self, klass):<br>
>         print "A::__init__()"<br>
>         self._klass = klass<br>
><br>
>     def __call__(self):<br>
>         print "A::__call__()"<br>
>         return self._klass()<br>
><br>
>     def __del__(self):<br>
>         print "A::__del__()"<br>
><br>
> class Parent1(object):<br>
>     def __init__(self):<br>
>         print "Parent1:: __init__()"<br>
>         super(Parent1, self).__init__()<br>
><br>
> class Parent2(object):<br>
>     def __init__(self):<br>
>         print "Parent2:: __init__()"<br>
>         super(Parent2, self).__init__()<br>
><br>
> @A<br>
> class B(Parent1, Parent2):<br>
>     def __init__(self):<br>
>         print "B::__init__()"<br>
>         super(B, self).__init__()<br>
><br>
> def main():<br>
>     b = B()<br>
><br>
> if __name__ == "__main__":<br>
>     main()<br>
><br>
><br>
> I decorate a class, say class B (whose object initiation and deletion I<br>
> wanted to capture) with a decorator class A. Please note that the class B<br>
> is derived from two classes - Parent1 & Parent2 and I want to use super()<br>
> method to initialise the parent classes.<br>
><br>
> When I executed the above code snippet, I ran into the following issue:<br>
><br>
><br>
> A::__init__()<br>
> A::__call__()<br>
> B::__init__()<br>
> Traceback (most recent call last):<br>
>   File "so.py", line 40, in <module><br>
>     main()<br>
>   File "so.py", line 36, in main<br>
>     b = B()<br>
>   File "so.py", line 10, in __call__<br>
>     return self._klass()<br>
>   File "so.py", line 32, in __init__<br>
>     super(B, self).__init__()<br>
> TypeError: must be type, not A<br>
> A::__del__()<br>
><br>
><br>
> When I commented "super(B, self).__init__()" in the class B :: __init__()<br>
> method, it returned an object of type B and I was able to see the prints<br>
> in the __call__ and __del__ methods but the __init__() methods of the base<br>
> classes (Parent1 & Parent2) are not called!<br>
><br>
> From the error message, what I could understand is - the object returned<br>
> by A::__call__() is not of type B but of type A. But when I put a print in<br>
> the A::__call__() I could see it returns an object of type B and not A.<br>
><br>
> Now the question is - With this approach to capture the initiation and<br>
> deletion events of an object, how do I initialise the base classes using<br>
> super()?<br>
<br>
</div></div>You'd have to introduce a naming convention or rewrite your class to be<br>
aware of the wrapping in some way:<br>
<div class=""><br>
@A<br>
class B(Parent1, Parent2):<br>
    def __init__(self):<br>
        print "B::__init__()"<br>
</div>        super(B._klass, self).__init__()<br>
<br>
Not pretty.<br>
<div class=""><br>
> Or, is there any other better way to capture the __call__ and __del__<br>
>  events for an object of a certain class - if so, how?!<br>
<br>
</div>Most certainly, but you have to give some details about what you are up to<br>
first.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:'courier new',monospace">Sorry, I should have described what I was trying!</div><div class="gmail_default" style="font-family:'courier new',monospace">
<br></div><div class="gmail_default" style="font-family:'courier new',monospace"><div class="gmail_default">I want to create a decorator which should do the following things:</div><div class="gmail_default"><ul><li>
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. <br></li><li>When an object of the decorated class is deleted, the record with this deleted objects name (i.e. <a href="http://object.id">object.id</a>) should be removed from the table. <br>
</li></ul></div><div class="gmail_default">You can safely assume that all the database operations are working fine!<br></div><div><br></div><div>Now, for example - consider the following snippet:</div><div><br></div><div>
@saveme</div><div><div>class A(object):</div><div>    def __init__(self, id):</div><div>        <a href="http://self.id">self.id</a> = id</div><div><br></div><div>@saveme</div><div>class B(object):</div><div>    def __init__(self, id):</div>
<div>        <a href="http://self.id">self.id</a> = id<br></div><div><br></div><div>"saveme" should do what I have explained earlier.</div><div><br></div><div>a1 = A("A1")</div><div>a2 = A("A2")</div>
<div>a3 = A("A3")</div><div>b1 = B("B1")</div><div>b2 = B("B2")</div><div><br></div><div><div>At this point if I query and print all the records in a table, I should get the following:</div><div>
output: ["A1", "A2", "A3", "B1", "B2"]</div></div><div><br></div><div>del a1</div><div>del a2</div><div>del a3</div><div>del b1</div><div>del b2</div></div><div><br></div>
<div><div>At this point, all entries in the table should be deleted; query should return an empty list!</div><div><br></div><div>And, I want to highlight that the classes that are being decorated with "saveme" can de derived classes too!</div>
<div><br></div><div>What is the best way to do this?!</div></div><div><br></div><div>Thank you,</div><div><br></div><div>Sangeeth</div></div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
> PS:<br>
> <a href="http://stackoverflow.com/questions/21826854/typeerror-when-using-super-
method-with-class-decorator-for-a-derived-class" target="_blank">http://stackoverflow.com/questions/21826854/typeerror-when-using-super-<br>
method-with-class-decorator-for-a-derived-class</a><br>
<br>
<br>
_______________________________________________<br>
Tutor maillist  -  <a href="mailto:Tutor@python.org">Tutor@python.org</a><br>
To unsubscribe or change subscription options:<br>
<a href="https://mail.python.org/mailman/listinfo/tutor" target="_blank">https://mail.python.org/mailman/listinfo/tutor</a><br>
</blockquote></div><br></div></div>