Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #67046
| Path | csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!xlned.com!feeder1.xlned.com!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail |
|---|---|
| Return-Path | <aleax@google.com> |
| X-Original-To | python-list@python.org |
| Delivered-To | python-list@mail.python.org |
| X-Spam-Status | OK 0.000 |
| X-Spam-Evidence | '*H*': 1.00; '*S*': 0.00; 'subject:: [': 0.04; 'argument': 0.05; 'explicitly': 0.05; 'baypiggies': 0.07; 'context': 0.07; 'nested': 0.07; 'table.': 0.07; '"__main__":': 0.09; '*args,': 0.09; '__init__': 0.09; '__name__': 0.09; 'alter': 0.09; 'correspond': 0.09; 'created,': 0.09; 'decorator': 0.09; 'derived': 0.09; 'executed': 0.09; 'function,': 0.09; 'instances.': 0.09; 'lawrence': 0.09; 'main()': 0.09; 'method,': 0.09; 'obj': 0.09; 'spec': 0.09; 'thus,': 0.09; 'todo:': 0.09; 'type,': 0.09; 'url:baypiggies': 0.09; 'cc:addr:python-list': 0.11; 'def': 0.12; 'stored': 0.12; 'suggest': 0.14; '"list': 0.16; '(say': 0.16; '**kwargs)': 0.16; '**kwargs):': 0.16; '24,': 0.16; '39,': 0.16; '54,': 0.16; '__del__': 0.16; 'a(object):': 0.16; 'argument)': 0.16; 'called,': 0.16; 'cc:addr:chennaipy': 0.16; 'class;': 0.16; 'cleans': 0.16; 'commented': 0.16; 'constructs': 0.16; 'deleted,': 0.16; 'deleted;': 0.16; 'deletion': 0.16; 'earlier.': 0.16; 'email addr:google.com>': 0.16; 'email name:baypiggies': 0.16; 'for,': 0.16; 'highlight': 0.16; 'ids.': 0.16; 'initiation': 0.16; 'instances,': 0.16; 'main():': 0.16; 'subject: \n ': 0.16; 'subject:Baypiggies': 0.16; 'tried:': 0.16; 'typeerror:': 0.16; 'unsafe': 0.16; 'appropriate': 0.16; 'wrote:': 0.18; 'alex': 0.19; 'properly': 0.19; 'replacing': 0.19; 'subject:] ': 0.20; 'seems': 0.21; '8bit%:5': 0.22; 'feb': 0.22; '>>>': 0.22; 'example': 0.22; 'cc:addr:gmail.com': 0.22; 'email addr:gmail.com>': 0.22; 'cc:addr:python.org': 0.22; 'print': 0.22; 'creating': 0.23; 'error': 0.23; 'entries': 0.24; 'manager.': 0.24; 'mon,': 0.24; 'question': 0.24; "i've": 0.25; 'options': 0.25; 'query': 0.26; 'references': 0.26; 'certain': 0.27; 'skip:" 20': 0.27; 'header:In-Reply-To:1': 0.27; 'record': 0.27; 'point': 0.28; 'function': 0.29; 'appear': 0.29; 'rest': 0.29; 'cc:2**2': 0.30; 'returned': 0.30; 'message- id:@mail.gmail.com': 0.30; 'url:mailman': 0.30; 'asked': 0.31; 'code': 0.31; '50,': 0.31; 'existence': 0.31; 'explained': 0.31; 'prints': 0.31; 'relies': 0.31; 'table,': 0.31; 'file': 0.32; 'class': 0.32; 'url:python': 0.33; '(i.e.': 0.33; '(most': 0.33; 'plain': 0.33; 'skip:# 10': 0.33; 'skip:& 30': 0.33; 'table': 0.34; 'skip:_ 10': 0.34; 'subject:the': 0.34; "i'd": 0.34; 'could': 0.34; 'classes': 0.35; 'something': 0.35; 'objects': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; '8bit%:9': 0.36; 'i.e.': 0.36; 'instances': 0.36; 'object,': 0.36; 'returning': 0.36; 'attention.': 0.68; 'incoming': 0.72; 'reliance': 0.72; 'records': 0.73; 'audience': 0.74; 'guaranteed': 0.75; 'unsubscribe:': 0.77; 'informed': 0.78; 'gain': 0.79; 'here!': 0.84; 'suits': 0.84; 'url:self': 0.84; 'avoided.': 0.91; 'capture': 0.91; 'cc:no real name:2**2': 0.91; 'subject:Class': 0.91 |
| DKIM-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=FjPMVGz04P9IyWpjq6OiRKaL3jIX1sBElPq8QXVqB70=; b=b84MaEZJiL1vp4B4uH5hHj1yCGBF+cN+w0ZHaLjbVH1WF7VbXuWjiskVB6712/gYaS 2/VRQS/hCWly4ZFWY1egMDGitXeB7tPCoieNJNv7j3PryBCYtA864Xnxjik2O2hgfvxK aeS4TXcQeoaYpH5BWXqjUM1hjvxjwz0bkSlGBIpLsB9tVWHYIYudYN5zo3Y6tM3tpMcM yyxdzoDQLIfvV8GsbhABNdv33X0o6Eqtx8La6AOphFWsHRtRvLl2oIeNu/GW1h8+El8q OxmlV2gu23mPXP62yf7vmoZB922aE71g6/g+2VlMNtzqOjGFIFiY1Nfq7kowwn3pZ1cJ U6vg== |
| X-Google-DKIM-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=FjPMVGz04P9IyWpjq6OiRKaL3jIX1sBElPq8QXVqB70=; b=DwaXPjgk0pKq2qdbtJlib4lKMDDRICGlWI2Ufi67NQcpKkcEs2XLxBA7wAR7FHVTqd uVeoJSA8ghv0p4wqHzpIHVMzCNtFm9CFgrdYQzja4kCYq6QUncgBO4QtRPkCFqJKRX8d Xy2046e20nvGJNLPg9eUrqvMb6vag81WoGUHAA/pTX7Zjnp+KtWkzVfrsv1AdtyKmGAE Q/hGKTiHCpMFhQXbqjVk4mtPIwWWwK56w1iMupuUGMPabJ0fcwlhW8IgQvKOc4dqrPTH aq0l47fryMTYfHz4DP/kFnBkdva3ByeVicR35A7Kgr54dRWkaG/fKzCrijjGJV1xdZoO 9e7w== |
| X-Gm-Message-State | ALoCoQmfBB1yRjtjoUQTzZuGlbzka5kk/Jor0WomM4MRKpM72hstoQ12j9boIFFkRipUIqIlUkvn5+TZdJ+v3WNqy0a8oRBTHsx53j0SFrONYAWH4RvbDXAr1g+ZM/rzmrLDcHSXP87fcwFZ0REVOBQaHB9BcaUbPmxLFV2jFSYO9BXBRykh8Dc+YEuH2pssVSw2PYft4NLdMgWNjSAY8GMUnLKYQc+iEw== |
| MIME-Version | 1.0 |
| X-Received | by 10.182.142.229 with SMTP id rz5mr2507229obb.12.1393350249091; Tue, 25 Feb 2014 09:44:09 -0800 (PST) |
| In-Reply-To | <CAHGToM+kWkqCVsK-UkL5MBMjdh6h9CAiz69r+KDsDm5D491-EQ@mail.gmail.com> |
| References | <CAPbKEUp_OS_PukUz2KObOSLQzjwGehPOfG4C-3Gq9qq=RaASgQ@mail.gmail.com> <CAE46Be9Ght7zj3rk=40=fKNmASq_1ER96Xp4PaPXLuiyMmbD1A@mail.gmail.com> <CAHGToM+kWkqCVsK-UkL5MBMjdh6h9CAiz69r+KDsDm5D491-EQ@mail.gmail.com> |
| Date | Tue, 25 Feb 2014 09:44:08 -0800 |
| Subject | Re: [Baypiggies] Class decorator to capture the creation and deletion of objects |
| From | Alex Martelli <aleax@google.com> |
| To | David Lawrence <david@bitcasa.com> |
| Content-Type | multipart/alternative; boundary=001a11c362e6a531d904f33ea2e8 |
| Cc | python-list@python.org, BayPiggies <baypiggies@python.org>, bangpypers@python.org, chennaipy@python.org |
| X-BeenThere | python-list@python.org |
| X-Mailman-Version | 2.1.15 |
| Precedence | list |
| List-Id | General discussion list for the Python programming language <python-list.python.org> |
| List-Unsubscribe | <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe> |
| List-Archive | <http://mail.python.org/pipermail/python-list/> |
| List-Post | <mailto:python-list@python.org> |
| List-Help | <mailto:python-list-request@python.org?subject=help> |
| List-Subscribe | <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.7356.1393350252.18130.python-list@python.org> (permalink) |
| Lines | 562 |
| NNTP-Posting-Host | 2001:888:2000:d::a6 |
| X-Trace | 1393350252 news.xs4all.nl 2977 [2001:888:2000:d::a6]:46304 |
| X-Complaints-To | abuse@xs4all.nl |
| Xref | csiph.com comp.lang.python:67046 |
Show key headers only | View raw
[Multipart message — attachments visible in raw view] - view raw
The best way to avoid relying on __del__ in this particular case may be to
hold, rather than a plain list of the IDs, a list of weak references to
instances. When the "list of IDs" is asked for, it goes through a property
that cleans up those weak refs that correspond to now-disappeared
instances, before returning the requested list of IDs. Now __del__ can
usefully be removed (as its existence may interfere with GC of cyclical
garbage), yet the list of IDs is guaranteed to return the list of
still-existing instances' IDs, no matter what constructs or idioms have
been used to create and remove instances.
This avoid relying on creators/destroyers of instances properly calling
release and/or using the appropriate context manager; such reliance is
sometimes inevitable, but for this particular spec it does not appear to
be, thus, it might best be avoided.
Alex
On Mon, Feb 24, 2014 at 7:46 PM, David Lawrence <david@bitcasa.com> wrote:
> 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 <aleax@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.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
>>>
>>
>>
>> _______________________________________________
>> Baypiggies mailing list
>> Baypiggies@python.org
>> To change your subscription options or unsubscribe:
>> https://mail.python.org/mailman/listinfo/baypiggies
>>
>
>
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Re: [Baypiggies] Class decorator to capture the creation and deletion of objects Alex Martelli <aleax@google.com> - 2014-02-25 09:44 -0800
csiph-web