[Python-Dev] 'With' context documentation draft (was Re: Terminology for PEP 343
Nick Coghlan
ncoghlan at gmail.com
Fri Jul 15 12:47:59 CEST 2005
M.-A. Lemburg wrote:
> This is exactly what I'm getting at: I can see the potential
> use for resource management (which is what started out the
> whole idea IIRC), but fail to see why you'd want to use it
> for anything more complicated than that.
The other suggested uses (redirecting stdout, logging exceptions, inserting
fences in markup, switching decimal context) aren't really more complicated.
They're just different cases of 'paired code' - code which consists of
'standard setup code', 'the unique bit', 'standard cleanup code'.
The longest example context manager in PEP 343 is only 11 lines long. Even the
wrapper to turn a generator into a context manager weighs in at only 23 lines.
> Once you start talking about contexts (which usually refers
> to a combination of environment, state and location) you
> have to explain things like nesting, scopes, combination
> of different contexts, their interaction with each other,
> etc. etc.
Except that context managers combine contexts in a very simple way - each one
is almost entirely independent of both its surroundings and its contents. Each
context manager takes a specific action to set the context up, and a specific
action to tear it down again afterwards. Its behaviour is dependent only on
the arguments that are passed to its constructor, and exceptions raised by its
contents.
The only way to make a context manager depend on its position in the code
(rather than the passed in arguments) is to use sys._getframe, and using that
is always considered an evil hack :)
> Note that hiding things away in smart objects like what
> you call "context managers" will not make programs easier
> to understand, unless the specific task that such a "context
> manager" is simple enough to grasp by just looking at its
> definition in the with statement... but then you'd not call
> it a "context manager".
Each one on its own may not be called a context manager, but we still need a
collective term that covers all of the simple (but different) cases of common
setup and cleanup code that we would like to factor out.
We tried 'resource managers' (which was too specific to one particular use
case), 'block managers' (a bit too close to the related-but-very-different
Ruby blocks) and 'suite managers' (which wasn't too bad, but not very
intuitive) along the way, but 'context managers' was the first one that really
seemed to adequately summarise the nature of the protocol - allowing a
programmer to factor out arbitrary setup and cleanup code that would otherwise
have to be reproduced inline everywhere they needed it.
> BTW, the same argument applies to decorators. Programs don't
> get easier to read or understand if you overload a function
> with lots and lots of hidden magic...
No argument here, but notice that the generic term 'decorator' tells you
nothing about what any *specific* decorator does. The obviousness needs to be
in the name of the decorator (such as 'classmethod'). The situation is the
same for context managers - to make the code easy to read, the method or
variable used to denote the context manager in the with statement must be well
named.
> @put_all_the_smart_stuff_here
> def program(context):
> return "42"
>
> Of course, you *could* do all these things and Python is
> not preventing you from doing so, but will life get easier ?
> I doubt it.
But what about:
for item in put_all_the_smart_stuff_here():
item.value = 42
The other guiding light in the terminology discussion was the existing concept
of iterables and iterators. Those can do just about anything you want, and
frequently hide a great deal of complexity. However, if they're well named,
then it is possible to read a for loop that uses them without batting an eyelid.
If the reader decides they need to know the details, they look up the
documentation of the iterator, just as they'd look up the details of a
decorator they didn't recognise. Once they've looked up the definition once,
instead of having to recognise a particular usage pattern in the code ("Oh,
that's doing 'X' again"), the reader simply has to recognise the name ("Oh,
that's the decorator/iterator/context manager that does 'X'")
> Let's keep things simple and Python nice.
Indeed - but I see being able to factor out common code as both simple *and*
nice, which is why I like the ideas of functions, iterators, decorators and
context managers :)
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list