Need some help with 'with'

Mike Kent mrmakent at cox.net
Wed Nov 28 05:13:48 CET 2007


I recently found myself needing to do this a lot:

lock a record in a file
read the record into a buffer
alter the buffer
write the buffer back to the record
unlock the record

I'd love to be able to create a context for this to use with the
'with' statement, something like:

from __future__ import with_statement
from contextlib import contextmanager
from fcntl import lockf, LOCK_EX, LOCK_UN

@contextmanager
def lockedRecord(fileObj, offset, length):
    lockf(fileObj, LOCK_EX, offset, length)
    try:
        fileObj.seek(offset)
        buff = fileObj.read(length)
        newBuff = (yield buff)
        fileObj.seek(offset)
        fileObj.write(newBuff)
    finally:
        lockf(fileObj, LOCK_UN, offset, length)

Which would let me write code like:

fileObj = open("myfile.dat", "r+b")

with lockedRecord(fileObj, 20, 10) as rec:
    newRec = rec.replace('foo', 'bar')
    # Somehow send newRec back into the context

I know you can now send data back into a generator via the send method
of the generator, however i don't seem to have access to the generator
object itself.

I figure that if instead of returning the buffer from the context
directly, I instead returned the buffer in a list, I could then change
the buffer, put it in the returned list, then I'd have access to it
back inside the context, but this seems a bit ugly.

Does anyone have insight into the right way of doing this?



More information about the Python-list mailing list