On 10 April 2013 21:45, Albert-Jan Roskam <fo...@yahoo.com> wrote:
>
>
>> Subject: Re: [Tutor] Appending an extra column in a data file
>>
> <snip>
>
>> The file you attached is a space-delimited text file. If you want to
>> add a third column with the value '1.0' on every row you can just do:
>>
>> with open('old.dat') as fin, open('new.dat', 'w') as
>> fout:
>>     for line in fin:
>>         fout.write(line[:-1] + ' 1.0\n')
>
> Is that Python 3.x? I thought this "double context manager" could only be 
> done with contextlib.nested, e.g.:
>>>> with contextlib.nested(open(fn, "rb"), open(fn[:-4] + "_out.dat", "wb")) 
>>>> as (r, w):
> ...     for inline in r:
> ...             w.write(inline + " " + "somevalue" + "\n")

The contextlib.nested context manager does not work properly. The docs
http://docs.python.org/2/library/contextlib.html#contextlib.nested
say that it was deprecated in Python 2.7. To quote:

'''Deprecated since version 2.7: The with-statement now supports this
functionality directly (without the confusing error prone quirks).'''

The reason for its deprecation was that it cannot catch errors raised
during the function calls that create the underlying context managers.
This means that if the first open succeeds and the second fails (e.g.
because the file doesn't exist) then the with statement has no way of
guaranteeing that the first file gets closed.

Eryksun has pointed out the downside in relation to breaking long
lines. My preferred solution is just to literally nest the with
statements:

with open('old.dat'):
    with open('new.dat', 'w'):
        for line in fin:
            fout.write(line[:-1] + ' 1.0\n')

If your use case is more complicated then Python 3.3 gives you the ExitStack:
http://docs.python.org/3.3/library/contextlib.html#contextlib.ExitStack


Oscar
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to