2013-04-15 13 views
13

Czy mogę zmodyfikować plik CSV w linii używając biblioteki CSV Pythona lub podobnej techniki?Edytowanie plików w formacie CSV Inline w Pythonie

Bieżąca przetwarzam plik i aktualizuję pierwszą kolumnę (pole nazwy), aby zmienić formatowanie. Uproszczona wersja mojego kodu wygląda następująco:

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) 

Filozofia działa, ale jestem ciekaw, czy mogę zrobić zmienił inline tak, że nie jestem powielenie pliku.

Próbowałem wykonać, ale to dołącza nowe rekordy na końcu pliku zamiast zastępowania ich.

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

Ogólnie, nie, nie możesz tego zrobić. Można odczytać wszystkie dane z pliku 'r'' i zawinąć je w obiekt' StringIO'. Następnie możesz przekazać to do czytnika csv, zamykając plik i otwierając ponownie do pisania ... – mgilson

Odpowiedz

35

Nie, nie powinieneś próbować pisać do pliku, z którego właśnie czytasz. Możesz może zrobić to, jeśli po przeczytaniu wiersza pozostaniesz niezaznaczony, ale nie jest to wskazane, szczególnie jeśli zapisujesz więcej danych niż czytasz.

Metoda kanoniczna polega na napisaniu do nowego, tymczasowego pliku i przeniesieniu go na miejsce nad starym plikiem, z którego czytasz.

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) 

zrobiłem wykorzystanie bibliotek tempfile i shutil tutaj, aby ułatwić zadanie.

4

Nie ma żadnego bazowego wywołania systemowego dla wstawiania danych do pliku. Możesz nadpisać, dodać i zastąpić. Ale wstawienie danych do środka oznacza odczytywanie i przepisywanie całego plikuod momentu, w którym dokonano edycji do końca.

Jako dwie metody można to zrobić (a) przeskoczyć cały plik do pamięci, wprowadzić tam zmiany, a następnie zrzucić wynik z powrotem na dysk lub (b) otworzyć tymczasowy plik wyjściowy, w którym zapisujesz wyniki, gdy czytasz plik wejściowy, a następnie zastępujesz stary plik nowym, gdy dojdziesz do końca. Jedna metoda wykorzystuje więcej pamięci RAM, druga wykorzystuje więcej miejsca na dysku.