[Python-ideas] A different kind of context manager
Kristján Valur Jónsson
kristjan at ccpgames.com
Mon Oct 21 23:16:54 CEST 2013
Ø Cool, sure. But what are the use cases that need this and can't be done easily with the existing design?
Exactly those I listed. Any form of execution that requires a "function" to be run. This include all existing threading/multiprocessing designs.
Ø How would making the code inside the with block a callable improve this?
It allows the "if" statement to be part of the context manager
Ø I think this code is easier to read than yours as the logic of whether or not the do_stuff_once block is executed is where it belongs -- not hidden in the context manager.
That is a matter of taste. Maybe it would make sense to pull other things out of the context manager too? But taste should not, IMHO, limit our options. If this is a common idiom, locking and executing once, why shouldn't we be able to write a clever macro/context manger/syntactic sugar to help us with that? Why insist on this verbosity?
Also, consider my argument that most context managers are written using the @contextmanager paradigm. We like this idiom so much because this is what we really want to do, call the code from a wrapper function.
If you look at the design of that context manager, it is not exactly straightforward. This suggests to me that maybe we took a wrong turn deciding on a context manager design. Maybe we should have selected one in which this sort of coding is its native, natural, form, rather than having this intermarriage kludge which turns an imperative-looking generator into the traditional context manager.
From: Bruce Leban [mailto:bruce at leapyear.org]
Sent: 21. október 2013 17:22
To: Kristján Valur Jónsson
Cc: python-ideas at python.org
Subject: Re: [Python-ideas] A different kind of context manager
On Mon, Oct 21, 2013 at 6:55 AM, Kristján Valur Jónsson <kristjan at ccpgames.com<mailto:kristjan at ccpgames.com>> wrote:
So, If this is the way people like to think about context managers, like writing wrapper functoins, why don't we turn them into proper wrapper functions?
<...> The cool thing here though, is that "code" could, for example, be run on a different tasklet. Or a different thread. Or a different universe.
Cool, sure. But what are the use cases that need this and can't be done easily with the existing design?
class NewContextManager(object):
# A context manager that locks a resource, then executes the code only if it is not recursing
def __init__(self, lock):
self.lock = lock
def __contextcall__(self, code):
with lock:
if lock.active:
return # This is where @contextmanager will stop you, you can't skip the 'yield'
lock.active = True
try:
return code(None) # optionally pass value to the code as in "with foo() as X"
finally:
lock.active = False
You can do that with current context managers:
with lock_once(x) as lock_acquired:
if lock_acquired: # was not already locked
do_stuff_once()
@contextmanager
def lock_once(lock):
if lock.active:
yield False
else:
lock.active = True
try:
yield True
finally:
lock.active = False
Note that I'm mimicking your lock/unlock code which of course is not the proper way to acquire/release a lock, but it gets the idea across. How would making the code inside the with block a callable improve this? I think this code is easier to read than yours as the logic of whether or not the do_stuff_once block is executed is where it belongs -- not hidden in the context manager. Note that my version also allows me to do this, which I can't easily do with your context manager:
with lock_once(x) as lock_acquired:
if lock_acquired: # was not already locked
do_stuff_once()
else:
log('Lock %r was already acquired', x)
do_stuff_every_time()
--- Bruce
I'm hiring: http://www.cadencemd.com/info/jobs
Latest blog post: Alice's Puzzle Page http://www.vroospeak.com<http://www.vroospeak.com/>
Learn how hackers think: http://j.mp/gruyere-security
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131021/6574f619/attachment-0001.html>
More information about the Python-ideas
mailing list