2013-04-15 7 views
13

Kann ich eine CSV-Datei inline mit Pythons CSV-Bibliothek oder einer ähnlichen Technik modifizieren?Inline-CSV-Dateibearbeitung mit Python

Aktuell Ich verarbeite eine Datei und aktualisiere die erste Spalte (ein Namensfeld), um die Formatierung zu ändern. Eine vereinfachte Version meiner Code sieht wie folgt aus:

with open('tmpEmployeeDatabase-out.csv', 'w') as csvOutput: 
    writer = csv.writer(csvOutput, delimiter=',', quotechar='"') 

    with open('tmpEmployeeDatabase.csv', 'r') as csvFile: 
     reader = csv.reader(csvFile, delimiter=',', quotechar='"') 

     for row in reader: 
      row[0] = row[0].title() 
      writer.writerow(row) 

Die Philosophie funktioniert, aber ich bin gespannt, ob ich einen Inline bearbeiten tun können, so dass ich nicht die Datei dupliziert bin.

Ich habe versucht, folgen Sie, aber das hängt die neuen Datensätze an das Ende der Datei, anstatt sie zu ersetzen.

with open('tmpEmployeeDatabase.csv', 'r+') as csvFile: 
    reader = csv.reader(csvFile, delimiter=',', quotechar='"') 
    writer = csv.writer(csvFile, delimiter=',', quotechar='"') 

    for row in reader: 
     row[1] = row[1].title() 
     writer.writerow(row) 
+0

Im Allgemeinen, nein, das geht nicht. Sie könnten alle Daten aus der "r" -Datei lesen und sie in ein "StringIO" -Objekt wickeln. Dann können Sie das an den CSV-Reader übergeben, die Datei schließen und zum Schreiben wieder öffnen ... – mgilson

Antwort

35

Nein, Sie sollten nicht versuchen, in die Datei zu schreiben, von der Sie gerade lesen. Sie können tun, wenn Sie seek ing nach dem Lesen einer Zeile zurück halten, aber es ist nicht ratsam, vor allem, wenn Sie mehr Daten zurückschreiben als Sie lesen.

Die kanonische Methode besteht darin, in eine neue, temporäre Datei zu schreiben und diese über die alte Datei, aus der Sie gelesen haben, in die richtige Position zu bringen.

from tempfile import NamedTemporaryFile 
import shutil 
import csv 

filename = 'tmpEmployeeDatabase.csv' 
tempfile = NamedTemporaryFile(delete=False) 

with open(filename, 'rb') as csvFile, tempfile: 
    reader = csv.reader(csvFile, delimiter=',', quotechar='"') 
    writer = csv.writer(tempfile, delimiter=',', quotechar='"') 

    for row in reader: 
     row[1] = row[1].title() 
     writer.writerow(row) 

shutil.move(tempfile.name, filename) 

I Verwendung der tempfile und shutil Bibliotheken hier gemacht haben, um die Aufgabe zu erleichtern.

4

Es gibt keinen zugrunde liegenden Systemaufruf für Einfügen von Daten in eine Datei. Sie können überschreiben, Sie können anhängen, und Sie können ersetzen. Aber das Einfügen von Daten in die Mitte bedeutet das Lesen und Neuschreiben der gesamten Datei von dem Punkt, an dem Sie Ihre Bearbeitung bis zum Ende vorgenommen haben. Die zwei Möglichkeiten, dies zu tun, sind entweder (a) schlürfen die gesamte Datei in den Speicher, machen Sie Ihre Änderungen dort, und dann das Ergebnis zurück auf die Festplatte, oder (b) öffnen Sie eine temporäre Ausgabedatei, wo Sie schreiben Ihre Ergebnisse, während Sie die Eingabedatei lesen, und ersetzen dann die alte Datei durch die neue, sobald Sie das Ende erreicht haben. Eine Methode verwendet mehr RAM, die andere benötigt mehr Speicherplatz.