Header written as row in CSV Python

十年热恋 提交于 2021-01-29 12:15:45

问题


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


回答1:


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)



回答2:


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 seeks 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.



来源:https://stackoverflow.com/questions/61242772/header-written-as-row-in-csv-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!