简体   繁体   中英

Header written as row in CSV Python

I have the following code which I am using to create and add a new row to a csv file.

def calcPrice(data):


   fieldnames = ["ReferenceID","clientName","Date","From","To","Rate","Price"]
   with open('rec2.csv', 'a') as csvfile:

     writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
     writer.writeheader()
     writer.writerow(data)

return However, it as the header as a new row as well. How can I prevent this? 在此处输入图像描述

Here's a link to the gist with the whole code: https://gist.github.com/chriskinyua/5ff8a527b31451ddc7d7cf157c719bba

You could check if the file already exists

import os

def calcPrice(data):

   filename = 'rec2.csv'
   write_header = not os.path.exists(filename)

   fieldnames = ["ReferenceID","clientName","Date","From","To","Rate","Price"]
   with open(filename, 'a') as csvfile:

     writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
     if write_header:
        writer.writeheader()
     writer.writerow(data)

Let's assume there's a function we can call that will tell us whether we should write out the header or not, so the code would look like this:

import csv

def calcPrice(data):

   fieldnames = ["ReferenceID","clientName","Date","From","To","Rate","Price"]
   with open('rec2.csv', 'a') as csvfile:

       writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
       if should_write_header(csvfile):
           writer.writeheader()
       writer.writerow(data)

What will should_write_header look like? Here are three possibilities. For all of them, we will need to import the io module:

import io

The logic of all these functions is the same: we want to work out if the end of the file is the same as the beginning of the file. If that is true, then we want to write the header row.

This function is the most verbose: it finds the current position using the file's tell method, moves to the beginning of the file using its seek method, then runs tell again to see if the reported positions are the same. If they are not it seek s back to the end of the file before returning the result. We don't simply compare the value of EOF to zero because the Python docs state that the result of tell for text files does not necessarily correspond to the actual position of the file pointer.

def should_write_header1(fileobj):
    EOF = fileobj.tell()
    fileobj.seek(0, io.SEEK_SET)
    res = fileobj.tell() == EOF
    if not res:
        fileobj.seek(EOF, io.SEEK_SET)
    return res

This version assumes that while the tell method does not necessarily correspond to the position of the file pointer in general, tell will always return zero for an empty file. This will probably work in common cases.

def should_write_header2(fileobj):
    return fileobj.tell() == 0

This version accesses the tell method of the binary stream that TextIOWrapper (the text file object class) wraps. For binary streams, tell is documented to return the actual file pointer position. This is removes the uncertainty of should_write_header2 , but unfortunately buffer is not guaranteed to exist in all Python implementations, so this isn't portable.

def should_write_header3(fileobj):
    return fileobj.buffer.tell() == 0

So for 100% certainty, use should_write_header1 . For less certainty but shorter code, use one of the others. If performance is a concern favour should_write_header3 , because tell in binary streams is faster than tell in text streams.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM