[Python-ideas] contextlib.maybe

Sven Marnach sven at marnach.net
Sun Dec 11 20:06:16 CET 2011


Terry Reedy schrieb am So, 11. Dez 2011, um 01:02:30 -0500:
> Expecting contextlib to have such a specialized context manager that
> does exactly what you want is perhaps too much.

I don't think this is a very specialised need.  It would overcome a
fundamental limitation of context managers compared to some clean-up
constructs in other languages.  An example is Go's 'defer', which is
Go's replacement for try/finally blocks and context managers.  It
defers a function call to the time the current function returns, and
guarantees the deferred call will be executed no matter how control
leaves the current function -- just like a 'finally' clause.

The advantage of 'defer' over 'with' and try/finally blocks is that it
is not a compound statement, so you can "conditionally add a 'finally'
clause".  Returning to the example from the original post, let's see
how it would look in Go:

    func Fn(a_file *os.File) (err os.Error) {
        if a_file == nil {
            a_file, err = os.Open(a_default_location, os.O_RDONLY, 0)
            if err != nil { return }
            defer a_file.Close()
        }
        // do stuff
        return
    }

to achieve exactly what is desired.  The line 'defer a_file.Close()'
is only executed when we actually need to close the file.

Note that the disadvantage of 'defer' is also that it is not a
compound statement -- it is bound to the block defined by the current
function and in this regard less flexible than 'with' blocks.

We could add our own version of 'defer' to Python by offering a
context manager 'Deferrer' with a 'push()' method to push a clean-up
call-back on the Deferrer's stack.  This design would offer the
combined advantages of both approaches described above.  I, for one,
do think that this would make a very worthwhile addition to the
'contextlib' module.

We discussed such a context manager less than two weeks ago on this
list

    http://mail.python.org/pipermail/python-ideas/2011-October/012418.html

and Jan Kaliszewski even provided an implementation:

    http://mail.python.org/pipermail/python-ideas/2011-October/012463.html

What do you think?

Cheers,
    Sven



More information about the Python-ideas mailing list