【问题标题】:Header written as row in CSV Python在 CSV Python 中写为行的标题
【发布时间】:2020-04-16 04:34:36
【问题描述】:

我有以下代码用于创建新行并将其添加到 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)
     writer.writeheader()
     writer.writerow(data)

返回 但是,它也作为标题作为新行。我怎样才能防止这种情况?

这里有一个链接到整个代码的要点:https://gist.github.com/chriskinyua/5ff8a527b31451ddc7d7cf157c719bba

【问题讨论】:

  • 不写标题?删除writer.writeheader()
  • 请出示您使用calcPrice的代码。
  • 还共享data 变量的输出。我相信您可能有一行包含data 中的标题。
  • 您好,谢谢。我无法在此处添加整个代码。我添加了一个要点的链接。
  • 你好@michaeldel,请找到我对这个问题的编辑。谢谢。

标签: python python-3.x csv


【解决方案1】:

你可以检查文件是否已经存在

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】:

假设我们可以调用一个函数来告诉我们是否应该写出标题,因此代码如下所示:

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)

should_write_header 会是什么样子?这里有三种可能性。对于所有这些,我们需要导入 io 模块:

import io

所有这些函数的逻辑都是一样的:我们要计算文件的结尾是否与文件的开头相同。如果是这样,那么我们要写标题行。

这个函数是最冗长的:它使用文件的tell方法找到当前位置,使用它的seek方法移动到文件的开头,然后再次运行tell来查看报告的位置是否是相同。如果它们不是 seeks 在返回结果之前返回文件末尾。我们不会简单地将 EOF 的值与零进行比较,因为 Python 文档指出 tell 对于文本文件的结果不一定对应于文件指针的实际位置。

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

此版本假设虽然tell 方法通常不一定对应于文件指针的位置,但tell 将始终为空文件返回零。这可能适用于常见情况。

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

此版本访问TextIOWrapper(文本文件对象类)包装的二进制流的tell 方法。对于二进制流,tell 被记录为返回实际的文件指针位置。这消除了should_write_header2 的不确定性,但不幸的是,buffer 并不能保证在所有 Python 实现中都存在,所以这不是可移植的。

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

因此,为了 100% 的确定性,请使用 should_write_header1。对于不太确定但更短的代码,请使用其他代码之一。如果性能是一个问题,那么喜欢should_write_header3,因为二进制流中的tellfaster,而不是文本流中的tell

【讨论】:

猜你喜欢
  • 2018-05-15
  • 2011-06-25
  • 1970-01-01
  • 2019-02-12
  • 2015-04-04
  • 2018-12-23
  • 1970-01-01
  • 2015-01-08
  • 2021-05-07
相关资源
最近更新 更多