Block-structured resource handling via decorators

John Perks and Sarah Mount johnandsarah at estragon.freeserve.co.uk
Fri Jul 29 18:11:37 EDT 2005


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.

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 name "do" is arbitrary; this method has the "mostly harmless"
side-effect of assigning None to a local variable with the function
name.)

I find it clear because I come from a C++/C#/Java background, and I
found C#'s using-blocks to very useful, compared to the explicit
finallys of Java. I know that Python's deterministic finalization sort
of achieves the same effect, but I had been led to believe there were
complications in the face of exceptions.

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.

If the last is the case, can someone let me know, and I'll put up the
code and explain how it all works. On the other hand, if there is
something wrong with it, please can someone tell me what it is?

Thanks

John Perks





More information about the Python-list mailing list