简体   繁体   English

一次打开CSV文件,然后从循环python向其中写入几行

[英]open a CSV file once and write several lines to it from a loop python

The following method: 方法如下:

def generateCSVfile(fileName,fileDescription,fileLocation,md5Hash):
    with open('deploymentTemplate.csv', 'w') as csvfile:
        createRow = csv.writer(csvfile,
                                 quoting=csv.QUOTE_MINIMAL)

This generates my CSV file but since I am calling it in a loop it just overrides itself. 这会生成我的CSV文件,但是由于我是在循环中调用它,因此它会覆盖自身。

generateCSVfile(name, fileDescription, filePath+"/"+name, md5Hash)

I am trying to find a way to generate the file, leave it open, call the above method and have all the text written to it without the file overriding itself. 我试图找到一种方法来生成文件,使其保持打开状态,调用上述方法,并在不覆盖文件自身的情况下将所有文本写入文件。

Use : open('deploymentTemplate.csv', 'a') to append values. 使用: open('deploymentTemplate.csv', 'a')附加值。

Syntax: open(<file_name> [,<mode>]) 语法: open(<file_name> [,<mode>])

Different modes are : 不同的模式是:

  • mode can be 'r' when the file will only be read 仅读取文件时,模式可以为'r'
  • 'w' for only writing (an existing file with the same name will be erased) 'w'仅用于写入(具有相同名称的现有文件将被删除)
  • 'a' opens the file for appending and any data written to the file is automatically added to the end. 'a'打开文件进行追加,写入文件的所有数据都会自动添加到末尾。
  • 'r+' opens the file for both reading and writing. 'r+'打开文件以供读取和写入。

    The mode argument is optional; mode参数是可选的; 'r' will be assumed if it's omitted. 如果省略,则假定为“ r”。

Eg : 例如:

with open("test.txt", "a") as myfile:
    myfile.write("appended text")

If the file needs to be emptied once per program run, but appended multiple times within a run, you could always just use a global (or class member state) to ensure it's only opened once. 如果文件需要在每次程序运行时清空一次,但是在一次运行中要追加多次,则始终可以使用全局(或类成员状态)来确保只打开一次。

import atexit

csvfile = None
def generateCSVfile(fileName,fileDescription,fileLocation,md5Hash):
    global csvfile
    if csvfile is None:
        # Lazily open file on first call
        csvfile = open('deploymentTemplate.csv', 'w')
        atexit.atexit(csvfile.close)  # Close cleanly on program exit

    try:
        csvwriter = csv.writer(csvfile, quoting=csv.QUOTE_MINIMAL, newline='')
        # do whatever writing you need to csvwriter
    finally:
        csvfile.flush()  # Match behavior of repeated with/open, force predictable flush

If there might be multiple CSV files involved, you might use a class with instance state and a method to do the writing, so each file can be independently cleared once and appended many times. 如果可能涉及多个CSV文件,则可以使用具有实例状态的类和一种方法来进行写入,因此每个文件可以独立清除一次并附加多次。 In this case, due to limits on the number of open file handles, reopening for append on each use is slower but safer than opening once and leaving open. 在这种情况下,由于打开文件句柄的数量受到限制,因此每次使用后重新打开以进行附加操作比打开一次并保持打开状态更慢但更安全。 You can use caching so the class is a singleton for any given file name too: 您可以使用缓存,因此该类对于任何给定的文件名也是单例的:

import weakref

class CSVGenerator:
    CACHE = {}
    CACHELOCK = threading.Lock()

    def __new__(cls, csvfilename):
        canonicalname = os.path.realpath(csvfilename)
        newself = super().__new__(cls)
        with cls.CACHELOCK:
            self = cls.CACHE.setdefault(canonicalname, newself)
            if newself is self:
                # First time we opened this file, clear file and initialize instance
                with open(canonicalname, 'w') as f:
                    pass
                self.csvfilename = canonicalname
                self.appendlock = threading.Lock()
        return self

    def generateCSVfile(self, fileName, fileDescription, fileLocation, md5Hash):
        with newself.appendlock, open(self.csvfilename, 'a', newline='') as csvfile:
            createRow = csv.writer(csvfile, quoting=csv.QUOTE_MINIMAL)
            # Perform writes to file

Usage of the class can be either: 该类的用法可以是:

 CSVGenerator(somecsvfilename).generateCSVfile(...args...)

which acquires an instance briefly (creating it if needed) then writes once, or it can create and store an instance and reuse it (saves the overhead of cache lookup, but functionally identical). 它会短暂获取一个实例(如果需要,可以创建一个实例),然后编写一次,或者它可以创建并存储实例并重用它(节省了缓存查找的开销,但功能相同)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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