Using "with open(filename, 'ab'):" and calling code only if the file is new?

Neil Cerutti neilc at norwich.edu
Wed Oct 30 09:23:52 EDT 2013


On 2013-10-30, Victor Hooi <victorhooi at gmail.com> wrote:
> Hi,
>
> I have a CSV file that I will repeatedly appending to.
>
> I'm using the following to open the file:
>
>     with open(self.full_path, 'r') as input, open(self.output_csv, 'ab') as output:
>         fieldnames = (...)
>         csv_writer = DictWriter(output, filednames)
>         # Call csv_writer.writeheader() if file is new.
>         csv_writer.writerows(my_dict)
>
> I'm wondering what's the best way of calling writeheader() only
> if the file is new?
>
> My understanding is that I don't want to use os.path.exist(),
> since that opens me up to race conditions.
>
> I'm guessing I can't use try-except with IOError, since the
> open(..., 'ab') will work whether the file exists or not.
>
> Is there another way I can execute code only if the file is new?

A heavy-duty approach involves prepending the old contents to a
temporary file.

fieldnames = (...)

with tempfile.TempDirectory() as temp:
    tempname = os.path.join(temp, 'output.csv')
    with open(tempname, 'wb') as output:
        writer = csv.DictWriter(output, fieldnames=fieldnames)
        writer.writeheader()
        try:
            with open(self.output_csv, 'b') old_data:
                reader = csv.DictReader(old_data)
                for rec in reader:
                    writer.writerow(rec)
        except IOError:
            pass
        with open(self.full_path, 'b') as infile:
            # etc...
    shutil.copy(tempname, self.output_csv)

This avoids clobbering output_csv unless new data is succesfully
written. I believe TempDirectory isn't available in Python 2, so
some other way of creating that path will be needed, and I'm too
lazy to look up how. ;)

-- 
Neil Cerutti



More information about the Python-list mailing list