On Thu, Jan 6, 2011 at 11:58 AM, Tal Einat <[email protected]> wrote:
> On Thu, Jan 6, 2011 at 1:33 AM, cool-RR <[email protected]> wrote: > >> Thanks for the critique Tal. >> >> I updated the `context_manager` module in response, here is the new >> version: >> >> >> https://github.com/cool-RR/GarlicSim/blob/development/garlicsim/garlicsim/general_misc/context_manager.py >> >> (Note that this is a link to my `development` branch, so it will get >> updated as I continue working on it.) >> >> In Thu, Jan 6, 2011 at 12:36 AM, Tal Einat <[email protected]> wrote: >> >>> 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." >>> >> >> Here's the new description I came up, tell me if you think it's good >> enough: >> >> >> Defines the `ContextManager` and `ContextManagerType` classes. >> >> These classes allow for greater freedom both when (a) defining context >> managers >> and when (b) using them. It allows defining context managers either by (1) >> using the classic `__enter__` and `__exit__` interface, or (2) using a >> stand-alone generator function or (3) using a class that defines a >> `manage_context` generator function. In addition, the `ContextManager` >> class >> allows using a context manager as a decorator to a function, which for >> some >> cases is a better alternative than using the `with` keyword. >> >> > I still find this to be too long, in the sense that I have to read the > entire paragraph just to get a basic idea of what this does. How about > keeping this, but adding to the first sentence, something like: > > Defines the `ContextManager` and `ContextManagerType` classes. Using > these to define context managers allows using such context managers as > decorators (in addition to their normal use) and supports writing context > managers in a new form (as well as the original forms). > Cool, I replaced mine with this one. > > >> >> >>> I must say, the actual benefits are really unclear. How is using >>> @MyContextManager() better than contextlib.ContextDecorator (the latter >>> being more explicit)? >>> >> >> How is `ContextDecorator` more explicit? The place where you write >> "ContextDecorator" is where you *define* you context manager, not where you >> *use* it. So when you use your context manager as a decorator using >> Foord's `ContextDecorator`, there is no reference to `ContextDecorator`, so >> I don't see how it's more explicit. >> > > You are correct, I misunderstood the use of ContextDecorator. So the use is > very similar. If the two classes are identical in this sense, you should > mention that, if not you must describe the differences. > There's this sentence in the docstring: "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`." I think it's good enough: I don't want to start describing `ContextManager` in terms of Foord's `ContextDecorator`, I'd rather describe it directly. Also the readers might not be familiar with `ContextDecorator`-- It's a relatively new addition and I'd bet that the vast majority of Python users aren't aware of it. > > >> >> >>> How is using the "manage_context()" method better than just defining a >>> context manager with a function and contextlib.contextmanager? >>> >>> - Tal >>> >> >> There are two cases that I can think of where it's better. In the version >> of `context_manager.py` you saw before I gave an example of the first, and >> in the new version that I linked to above I also explain the second. >> >> The first case where this is helpful is when you want a context manager >> which calls another context manager. For example, this code: >> >> class MyContextManager(ContextManager): >> def manage_context(self): >> with some_lock: >> yield self >> >> >> Is much nicer in my opinion than this code, which is its equivalent: >> >> class MyContextManager(ContextManager): >> def __enter__(self): >> some_lock.__enter__() >> return self >> def __exit__(self, *exc): >> return some_lock.__exit__(*exc) >> >> >> As for the second case, I'll quote the new version of the docstring: >> >> Another advantage of this approach over `__enter__` and `__exit__` is >> that >> it's better at handling exceptions, since any exceptions would be raised >> inside `manage_context` where we could `except` them, which is much more >> idiomatic than the way `__exit__` handles exceptions, which is by >> receiving their type and returning whether to swallow them or not. >> >> > The same can be said for defining context manager via generator functions > and contextlib.contextmanager. How is your context_manager() form of > definition better or different than that? > It's true, it's the same mechanism as `contextlib.contextmanager`; The difference is that in `contextlib.contextmanager` you create a bare context manager which can do nothing beyond being a context manager. But when you subclass from `ContextManager` and use `manage_context`, you can put whatever else you want in this class; You can define methods, inherit from other classes, etc. For example, if you already have some class `Foobar` in your project and you want it to behave as a generator-style context manager, inheriting from my `ContextManager` is the only solution. (Except coding your own, of course.) > I hope this is written clearly enough; Possibly an example for this case >> should be included in the docstring. I'm not sure though. >> > > It is technically clear. However, the reasons someone would want to use it > instead of the existing forms of writing context managers aren't clear at > all. You should give actual examples of things that can be done with your > classes that can't be done otherwise (or would be significantly more > cumbersome). > > - Tal > I added an example for the first case now. I tried giving an example for the second one, but couldn't find an impressive enough example. I have a few places where it saved me a few dozen characters, but it's not impressive enough. So I think I'll stay without an example for the second case. All the changes can be seen in the most updated version here: https://github.com/cool-RR/GarlicSim/blob/development/garlicsim/garlicsim/general_misc/context_manager.py Ram.
_______________________________________________ Python-il mailing list [email protected] http://hamakor.org.il/cgi-bin/mailman/listinfo/python-il
