contextlib.nested()

brasse thebrasse at gmail.com
Fri Nov 7 02:59:07 EST 2008


On Nov 6, 5:45 pm, "Diez B. Roggisch" <de... at nospam.web.de> wrote:
> > If you had a class that wanted to acquire some external resources that
> > must be released at some point, how would you rewrite the code from my
> > example?
>
> If you *can*, use a context. Use __enter__ and __exit__. Try really hard to
> use it that way.
>

My case becomes something like this:

from __future__ import with_statement

from contextlib import nested

class Foo(object):

    def __init__(self, tag, fail=False):
        print 'ctor', tag
        self.tag = tag
        self.fail = fail

    def __enter__(self):
        if self.fail:
            print 'fail', self.tag
            raise Exception()
        print '__enter__ acquire resource', self.tag
        return self

    def __exit__(self, *args):
        print '__exit__ release resource', self.tag

with nested(Foo('a'), Foo('b', True)) as (a, b):
    print a.tag
    print b.tag

When using Foo objects in a with statement this works good for me. But
what if I want to use Foo objects as members in a class for example?
Since we now must contruct an instance of Foo in two stages the code
becomes less than ideal.

def __init__(self):
    self.x = Foo()
    self.x.__enter__()

Perhaps there is no way to write classes that fits neatly into all (or
even these two) usage scenarios?

> If not - create a specific finalize-method or some such, and try not to
> forget to call that. Potentially with an atexit-handler or some such.
>

It seems to me that I have to use the with statement (or some try-
finally construct) to be able to release all resources when my code
throws exceptions(). Just remembering to call close/finalize/destroy
will not be enough.

:.:: mattias



More information about the Python-list mailing list