Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #67014 > unrolled thread
| Started by | Alex Martelli <aleax@google.com> |
|---|---|
| First post | 2014-02-24 18:24 -0800 |
| Last post | 2014-02-24 18:24 -0800 |
| Articles | 1 — 1 participant |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [Baypiggies] Class decorator to capture the creation and deletion of objects Alex Martelli <aleax@google.com> - 2014-02-24 18:24 -0800
| From | Alex Martelli <aleax@google.com> |
|---|---|
| Date | 2014-02-24 18:24 -0800 |
| Subject | Re: [Baypiggies] Class decorator to capture the creation and deletion of objects |
| Message-ID | <mailman.7336.1393295100.18130.python-list@python.org> |
[Multipart message — attachments visible in raw view] — view raw
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.saravanaraj@gmail.com> wrote:
> This question was initially asked in tutor@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
> Baypiggies@python.org
> To change your subscription options or unsubscribe:
> https://mail.python.org/mailman/listinfo/baypiggies
>
Back to top | Article view | comp.lang.python
csiph-web