2012-09-25 9 views
7

Staram się pisać listy listy do nowego pliku, ale ja dostaję ten błąd:TypeError: oczekiwano obiektu bufor charakter

Traceback (most recent call last): File "", line 1, in dowork() File "C:\Python27\work\accounting\formatting quickbooks file\sdf.py", line 11, in dowork WriteFile() File "C:\Python27\work\accounting\formatting quickbooks file\sdf.py", line 71, in WriteFile f.write(thefile) TypeError: expected a character buffer object

Jak pisać listy listy do plik?

To jest jak piszę:

def WriteFile(): 
    global thefile 
    f = open("output"+'.csv','w') 
    f.seek(0) 
    f.write(thefile) 
    f.close() 

i tu jest kompletnym źródłem jeśli jest to potrzebne:

import csv 

thefile = [] 
output = [] 

def dowork(): 
    sourceFile='e.csv' 
    thefile=ReadFile(sourceFile) 
    CleanFile(sourceFile) 
    ProcessFile() 
    WriteFile() 

def ReadFile(filename): 
    return list(csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"'))[1:] 

def CleanFile(sourceFile): 
    global thefile 
    thefiletmp=[] 
    for i, line in enumerate(thefile): 
     if line[2]=='': 
      del thefile[i] 
     else: 
      thefiletmp.append(line[4:]) 
    thefile=thefiletmp 


def ProcessFile(): 
    global thefile 
    iCompany=1 
    iNum=0 
    iDate=2 
    iAging=3 
    iBalance=4 
    COMPANIES=GetDistinctValues(1) 
    mytemparray=[] 
    mytempfile=[] 
    for company in COMPANIES: 
     for line in thefile: 
      if line[iCompany]==company: 
       mytemparray.append(line[iCompany]) 
       mytemparray.append(line[iNum]) 
       mytemparray.append(line[iDate]) 
       if line[2] in range(0,31): 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append('0') 
       if line[2] in range(31,61): 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
        mytemparray.append('0') 
       if line[2] in range(61,91): 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
       if line[2] >90: 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
       mytempfile.append(mytemparray) 
       mytemparray=[] 
    thefile=mytempfile 

def WriteFile(): 
    global thefile 
    f = open("output"+'.csv','w') 
    f.seek(0) 
    f.write(thefile) 
    f.close() 

def GetDistinctValues(theColumn): 
    return sorted(list(set(line[theColumn] for line in thefile))) 
+0

Naprawdę powinieneś zastąpić zmienną globalną zmienną, którą przekazałeś do każdej funkcji, i zamknąć pliki, gdy skończysz. A teraz, gdy widzimy cały kod, zdecydowanie sugeruję reorganizację, więc masz funkcję 'ProcessLine' (możesz po prostu odwrócić pętle' line' i 'company'), i po prostu filtruj linię po linii, więc nie potrzebuję listy i nie trzeba usuwać rzeczy z listy w miejscu itd. W ten sposób wszystko byłoby znacznie prostsze. – abarnert

+0

możliwy duplikat [TypeError: oczekiwany obiekt bufora znaków - podczas próby zapisania liczby całkowitej do pliku tekstowego] (http: // stackoverflow.com/pytania/9786941/TypeError oczekiwano-a-character-bufor-przedmiot-while-stara-to-save-całkowitą-do) –

Odpowiedz

12

Co się komunikat o błędzie mówiąc, jest to, że nie można pisać listy do pliku, tylko „obiekt bufor charakter”, czyli ciąg lub coś innego, który działa trochę jak łańcuch.

Jeśli chcesz po prostu pisać listy do pliku w ten sam sposób chcesz wydrukować je do konsoli, można napisać str(thefile) lub repr(thefile) (lub nawet użyć składni przekierowania w print zamiast korzystania file.write).

Ale używasz modułu csv czytać wejście i wyjście przypuszczalnie chcą w tym samym formacie, więc prawdopodobnie chcesz użyć csv pisać też.

Czytasz tak:

list(csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"'))[1:] 

więc napisać tak:

csv.writer(open('foo.csv', 'wb'), delimiter=',', quotechar='"').writerows(thefile) 

należy wspomnieć, że nie będę struktury kodu tak w pierwszej kolejności; Zrobiłbym coś takiego:

with open('input.csv', 'rb') as infile, open('output.csv', 'wb') as outfile: 
    incsv = csv.reader(infile, delimiter=',', quotechar='"') 
    outcsv = csv.writer(outfile, delimiter=',', quotechar='"') 
    incsv.read() # skip first line 
    for line in incsv: 
    if line[3] != '': 
     outcsv.write(ProcessLine(line)) 
+0

+1, co jest naprawdę potrzebne. –

3

Nie można pisać listy do pliku; możesz napisać tylko ciąg. Konwertuj listę do łańcucha w jakiś sposób, lub iteruj po liście i napisz element na raz. Lub używasz modułu csv, użyj go, aby napisać do pliku.

Wywołanie czegoś innego niż plik (na przykład lista) thefile może doprowadzić do zamieszania, przy okazji.

+0

Ha, poddaję się, wygrać: D –

+0

TypeError: pozycja 0 sekwencja: oczekiwany ciąg , lista znaleziona –

+0

dzięki możesz you nam, jak mogę użyć modułu csv do napisania? –

2

thefile jest lista list, a nie bufor charakter.

for sublist in thefile: 
    f.write("".join(sublist)) # perhaps 

jest jakaś zła tutaj, wykorzystując globalny, nazywania listy thefile ...

(Prawidłowa odpowiedź to abarnert'S).

Powiązane problemy