Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #6083

Re: Writing multiple files with with-context

References <5142852e-bab9-4e39-a49b-0229e900e97d@glegroupsg2000goo.googlegroups.com>
From Ian Kelly <ian.g.kelly@gmail.com>
Date 2011-05-23 11:31 -0600
Subject Re: Writing multiple files with with-context
Newsgroups comp.lang.python
Message-ID <mailman.1981.1306171914.9059.python-list@python.org> (permalink)

Show all headers | View raw


On Sun, May 22, 2011 at 8:48 PM, Shunichi Wakabayashi
<shunichi_wakabayashi@yahoo.co.jp> wrote:
> One idea is using contextlib.nested(),
>
> from contextlib import nested
>
> with nested(*[open('list_%d.txt' % i, 'w') for i in range(LIST_LEN)]) as fobjlist:
>  for i in range(1000):
>    fobjlist[random.randrange(LIST_LEN)].write(str(i)+"\n")
>
> with nested(*[open('dict_%s.txt' % k, 'w') for k in DICT_KEYS]) as fobjlist:
>  fobjdict = dict(zip(DICT_KEYS, fobjlist)) #convert list to dict
>  for i in range(1000):
>    fobjdict[random.choice(DICT_KEYS)].write(str(i)+"\n")
>
> On Python2.x, this is OK. but 3.x warns that nested() is deprecated.

Not merely deprecated.  It has already been removed in 3.2.

> Another idea is to make container classes having __exit__() myself.
>
> class MyList(list):
>  def __enter__(self):
>    return [ v.__enter__() for v in self ]
>  def __exit__(self, exc_type, exc_value, traceback):
>    ret = False
>    for v in self:
>      if v.__exit__(exc_type, exc_value, traceback):
>        ret = True
>        exc_type = exc_value = traceback = None
>    return ret

This has a number of subtle bugs in it:

1) Each context manager's __exit__ method is not loaded before the
corresponding __enter__ method is invoked.
2) If the second context manager's __enter__ method raises an
exception, the first context manager's __exit__ method is never
called, breaking the with statement guarantee.
3) The __exit__ methods are called in the same order that the
__enter__ methods were called.  Since they form a stack, they should
be called in the reverse order.

These highlight the complexity of handling context managers correctly,
which I think suggests that a custom implementation is probably a bad
idea.

> So, do you have another, more smart and pythonic way?

Copy the implementation of contextlib.nested to your own custom module
and use that.  The last revision prior to its removal is here:

http://hg.python.org/cpython/file/45506be44514/Lib/contextlib.py

Back to comp.lang.python | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

Writing multiple files with with-context Shunichi Wakabayashi <shunichi_wakabayashi@yahoo.co.jp> - 2011-05-22 19:48 -0700
  Re: Writing multiple files with with-context Ian Kelly <ian.g.kelly@gmail.com> - 2011-05-23 11:31 -0600

csiph-web