[Tutor] Appending an extra column in a data file
Oscar Benjamin
oscar.j.benjamin at gmail.com
Wed Apr 10 23:46:20 CEST 2013
On 10 April 2013 21:45, Albert-Jan Roskam <fomcl at 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
More information about the Tutor
mailing list