Python, пустой файл после записи csv.. снова

#python #csv #writer

#python #csv #запись

Вопрос:

Моя программа на python перебирает кучу csv-файлов, читает их и записывает определенные столбцы в файле в другой файл csv. Во время работы программы я вижу, что файлы записываются правильно, но как только программа завершена, все файлы, которые я только что написал, становятся пустыми.

Решение для всех других подобных потоков, похоже, заключается в правильном закрытии файла, в который вы записываете, но, похоже, я не могу понять, что я делаю неправильно. Кто-нибудь?

 import os
import csv

def ensure_dir(f):
    d = os.path.dirname(f)
    if not os.path.exists(d):
        os.makedirs(d)

readpath = os.path.join("d:\", "project")
savepath=os.path.join("d:\", "save")
ensure_dir(savepath)
contents_1=os.listdir(readpath)
for i in contents_1[1:len(contents_1)]:
    readpath_2=os.path.join(readpath, i)
    if os.path.isdir(readpath_2)== True :
        contents_2=os.listdir(readpath_2)
        for i in contents_2:
            readpath_3=os.path.join(readpath_2, i)
            if os.path.isfile(readpath_3)== True :
                savefile=savepath   "\"   i
                savefile = open(savefile, 'wb')
                writer = csv.writer(savefile, delimiter=';')
                readfile=open(readpath_3, 'rb')
                reader = csv.reader(readfile, delimiter=';')
                try:
                    for row in reader:
                        writer.writerow([row[0], row[3]])
                except:
                    print(i)
                finally:
                    savefile.close()
                    readfile.close()
  

Комментарии:

1. Вы должны использовать try..finally with оператор or — для чистого доступа к файлам без этих проблем.

2. Над какой операционной системой вы работаете?

3. Не то, чтобы это было вашей проблемой, но добавление == True к условному является избыточным (и немного глупым), и использование "\" i для построения пути вместо использования os.path.join нарушает совместимость с операционными системами, отличными от Windows.

4. @ms4py добавление finally, похоже, не решает проблему. Я надеялся, что будет решение без необходимости использовать оператор with.

5. У вас есть except: print(i) там. Он что-нибудь печатает? Кроме того, вы убедились, что файлы, из которых вы читаете, содержат данные?

Ответ №1:

savefile=savepath "\" i ошибка. Если оба "d:\projectax.csv" и "d:\projectbx.csv" существуют, то вы будете записывать savepath "\" i более одного раза. Если второй путь является пустым "x.csv" , то он перезапишет результат пустым файлом.

Попробуйте это вместо:

 import os
import csv

def ensure_dir(f):
    d = os.path.dirname(f)
    if not os.path.exists(d):
        os.makedirs(d)

readpath = os.path.join("d:\", "project")
savepath = os.path.join("d:\", "save")

ensure_dir(savepath)

for dname in os.listdir(readpath)[1:]:
    readpath_2 = os.path.join(dname, fname)
    if not os.path.isdir(readpath_2):
        continue
    for fname in os.listdir(readpath_2)
        fullfname = os.path.join(readpath_2, fname)
        if not os.path.isfile(fullfname):
            continue
        savefile = open(savepath   "\"   dname   "_"   fname, wb)
        writer = csv.writer(savefile, delimiter=';')
        readfile=open(fullfname, 'rb')
        reader = csv.reader(readfile, delimiter=';')
        try:
            for row in reader:
                writer.writerow([row[0], row[3]])
        except:
            print(i)
        finally:
            savefile.close()
            readfile.close()
  

Этот код может быть значительно улучшен с os.walk

Комментарии:

1. Спасибо, работает как шарм. И спасибо за совет по os.walk.

Ответ №2:

Цитирование из документации python:

Если csvfile является файловым объектом, он должен быть открыт с флагом ‘b’ на платформах, где это имеет значение.

Измените флаги ‘w’ и ‘r’ на ‘wb’ и ‘rb’.

Ответ №3:

(1) Ваш внешний цикл и ваш внутренний цикл используются i в качестве переменной цикла. Это не дает надежды на (а) понимание человеком (б) правильную работу.

(2) except: print(i) … Что??? Я бы посоветовал вам удалить попытку / исключение и исправить любые ошибки, с которыми вы столкнетесь.