[Python-il] What do you think about my `ContextManager`?
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
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
>>> Defines the `ContextManager` and `ContextManagerType` classes.
>>> These classes allow for greater freedom both when (a) defining context
>>> 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
>>> has their own advantages and disadvantages over the others.
>>> 1. The classic way to define a context manager is to define a class
>>> `__enter__` and `__exit__` methods. This is allowed, and if you do
>>> 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:
>>> def MyContextManager():
>>> pass # clean-up
>>> This usage is nothing new; It's also available when using the
>>> library's `contextlib.contextmanager` decorator. One thing that is
>>> here that `contextlib` doesn't allow is to yield the context manager
>>> by doing `yield SelfHook`.
>>> 3. The third and novel way is by defining a class with a
>>> method which returns a decorator. Example:
>>> class MyContextManager(ContextManager):
>>> def manage_context(self):
>>> with some_lock:
>>> yield self
>>> 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
>>> 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:
>>> 2. As a decorator to a function
>>> def do_stuff():
>>> pass # doing stuff
>>> When the `do_stuff` function will be called, the context manager will
>>> used. This functionality is also available in the standard library of
>>> Python 3.2+ by using `contextlib.ContextDecorator`, but here it is
>>> with all the other goodies given by `ContextManager`.
>>> That's it. Inherit all your context managers from `ContextManager` (or
>>> your generator functions with `ContextManagerType`) to enjoy all these
>>> Ram Rachum
>>> Python-il mailing list
>>> Python-il at hamakor.org.il
> Ram Rachum
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-il