[Python-il] What do you think about my `ContextManager`?

Tal Einat taleinat at gmail.com
Thu Jan 6 00:36:59 IST 2011


(I just hit Reply, usually that replies to the list...)

How about something like: "A class for writing enhanced context managers.
Allows using context managers as decorators, a new succinct way to define
context managers, and some other goodies."

I must say, the actual benefits are really unclear. How is using
@MyContextManager() better than contextlib.ContextDecorator (the latter
being more explicit)? How is using the "manage_context()" method better than
just defining a context manager with a function and
contextlib.contextmanager?

- Tal

On Wed, Jan 5, 2011 at 5:13 PM, cool-RR <cool-rr at cool-rr.com> wrote:

> Yes, I agree that's kind of an opaque description. But I haven't been able
> to come up with a description which (a) explains enough and (b)
> is succinct enough. Do you have a suggestion?
>
> Also, I think you should be sending critiques on the list; Other people may
> have interesting opinions.
>
>
> On Wed, Jan 5, 2011 at 9:29 AM, Tal Einat <taleinat at gmail.com> wrote:
>
>> "Allows greater freedom" isn't much of a description. I had to read
>> through the entire docstring to understand what it does. You should make it
>> very clear what new functionality this supplies compared to the basic stuff.
>>
>> On Tue, Jan 4, 2011 at 7:55 PM, cool-RR <cool-rr at cool-rr.com> wrote:
>>
>>> Hello folks.
>>>
>>> Ever since Michael Foord talked about `ContextDecorator` in python-ideas
>>> I've been kicking around an idea for my own take on it. It's a
>>> `ContextManager` class which provides the same thing that Foord's
>>> `ContextDecorator` does, but also provides a few more goodies, chief of
>>> which being the `manage_context` method.
>>>
>>> I've been working on this for a few days and I think it's ready for
>>> review. It's well-tested and extensively documented. I started using it
>>> wherever I have context managers in GarlicSim.
>>>
>>> I'll be happy to get your opinions on my approach and any critiques you
>>> may have. If there are no problems with this approach, I'll probably release
>>> it with GarlicSim 0.6.1 and blog about it.
>>>
>>> Here is my `context_manager` module<https://github.com/cool-RR/GarlicSim/blob/first_context_manager_review/garlicsim/garlicsim/general_misc/context_manager.py>.
>>> Here are its tests<https://github.com/cool-RR/GarlicSim/tree/first_context_manager_review/garlicsim/test_garlicsim/test_general_misc/test_context_manager>
>>> .
>>>
>>> Following is the module's docstring which explains the module in more
>>> detail.
>>>
>>> Ram.
>>>
>>> Defines the `ContextManager` and `ContextManagerType` classes.
>>>
>>> These classes allow for greater freedom both when (a) defining context
>>> managers
>>> and when (b) using them.
>>>
>>> Inherit all your context managers from `ContextManager` (or decorate your
>>> generator functions with `ContextManagerType`) to enjoy all the benefits
>>> described below.
>>>
>>>
>>> Defining context managers
>>> -------------------------
>>>
>>> There are 3 different ways in which context managers can be defined, and
>>> each
>>> has their own advantages and disadvantages over the others.
>>>
>>>  1. The classic way to define a context manager is to define a class
>>> with
>>>     `__enter__` and `__exit__` methods. This is allowed, and if you do
>>> this
>>>     you should still inherit from `ContextManager`. Example:
>>>
>>>         class MyContextManager(ContextManager):
>>>             def __enter__(self):
>>>                 pass # preparation
>>>             def __exit__(self, type_=None, value=None, traceback=None):
>>>                 pass # cleanup
>>>
>>>  2. As a decorated generator, like so:
>>>
>>>         @ContextManagerType
>>>          def MyContextManager():
>>>             try:
>>>                 yield
>>>             finally:
>>>                 pass # clean-up
>>>
>>>     This usage is nothing new; It's also available when using the
>>> standard
>>>     library's `contextlib.contextmanager` decorator. One thing that is
>>> allowed
>>>     here that `contextlib` doesn't allow is to yield the context manager
>>> itself
>>>     by doing `yield SelfHook`.
>>>
>>>  3. The third and novel way is by defining a class with a
>>> `manage_context`
>>>     method which returns a decorator. Example:
>>>
>>>         class MyContextManager(ContextManager):
>>>             def manage_context(self):
>>>                 do_some_preparation()
>>>                 try:
>>>                     with some_lock:
>>>                         yield self
>>>                  finally:
>>>                     do_some_cleanup()
>>>
>>>     This approach is sometimes cleaner than defining `__enter__` and
>>>     `__exit__`; Especially when using another context manager inside
>>>     `manage_context`. In our example we did `with some_lock` in our
>>>     `manage_context`, which is shorter and more idiomatic than calling
>>>     `some_lock.__enter__` in an `__enter__` method and
>>> `some_lock.__exit__` in
>>>     an `__exit__` method.
>>>
>>>
>>> These were the different ways of *defining* a context manager. Now let's
>>> see
>>> the different ways of *using* a context manager:
>>>
>>>
>>> Using context managers
>>> ----------------------
>>>
>>> There are 2 different ways in which context managers can be used:
>>>
>>>  1. The plain old honest-to-Guido `with` keyword:
>>>
>>>        with MyContextManager() as my_context_manager:
>>>            do_stuff()
>>>
>>>  2. As a decorator to a function
>>>
>>>         @MyContextManager()
>>>         def do_stuff():
>>>            pass # doing stuff
>>>
>>>     When the `do_stuff` function will be called, the context manager will
>>> be
>>>     used. This functionality is also available in the standard library of
>>>     Python 3.2+ by using `contextlib.ContextDecorator`, but here it is
>>> combined
>>>     with all the other goodies given by `ContextManager`.
>>>
>>>
>>> That's it. Inherit all your context managers from `ContextManager` (or
>>> decorate
>>> your generator functions with `ContextManagerType`) to enjoy all these
>>> benefits.
>>>
>>>
>>> --
>>> Sincerely,
>>> Ram Rachum
>>>
>>> _______________________________________________
>>> Python-il mailing list
>>> Python-il at hamakor.org.il
>>> http://hamakor.org.il/cgi-bin/mailman/listinfo/python-il
>>>
>>>
>>
>
>
> --
> Sincerely,
> Ram Rachum
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://hamakor.org.il/pipermail/python-il/attachments/20110106/03a6b5d7/attachment-0001.htm>


More information about the Python-il mailing list