Block-structured resource handling via decorators

Mike Meyer mwm at mired.org
Fri Jul 29 20:23:32 EDT 2005


"John Perks and Sarah Mount" <johnandsarah at estragon.freeserve.co.uk> writes:

> When handling resources in Python, where the scope of the resource is
> known, there seem to be two schools of thought:
>
> (1) Explicit:
> f = open(fname)
> try:
>     # ...
> finally:
>     f.close()
>
> (2) Implicit: let the GC handle it.

The only cases I see the first school of thought is when the resource
in question is "scarce" in some way. For example, most OS's place a
limit on the number of open files a process can have, some rather
tight. CPython's garbage collector will close an open file when it
leaves scope. Jython's GC will close it when the file is collected,
but you have no idea of when that will be, and an "open" failing won't
trigger a GC. So in this case, the first form is less likely to fail
unexpectedly.

> I've come up with a third method that uses decorators to achieve a
> useful mix between the two. The scope of the resource is clear when
> reading the code (useful if the resource is only needed in part of a
> function), while one does not have to write an explicit cleanup. A
> couple of examples:
>
> @withFile(fname, 'w')
> def do(f):
>     # ... write stuff into file f ...
>
> @withLock(aLock):
> def do():
>     # ... whatever you needed to do once the lock was acquired,
>     # safe in the knowledge it will be released afterwards ...
>
> The implementation is easily extensible: a handler for a new type of
> resource can be written in as a couple of lines. For the examples above:
>
> class withFile(blockScopedResource):
>     init, cleanup = open, 'close'
>
> It's so simple I was wondering why I haven't seen it before. Possibly:
>   it's a stupid idea and I just can't see why;
>   everyone knows about it except me;
>   it's counter-intuitive (that's not the way decorators were intended);
>   it's "writing C# in Python" or in some other way unPythonic;
>   I've actually had an idea that is both Original and non-Dumb.

Well, I'd say that using a string for cleanup and a function for init
is unpythonic. But the general idea seems to be a good one. Making it
easy to deal with resources that must be explicitly released is a good
thing. The question is whether having to turn your scope into a
function to do this is more trouble than it's worth.

I'd certainly be interested in seeing the implementation.

    <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list