#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)
… Что??? Я бы посоветовал вам удалить попытку / исключение и исправить любые ошибки, с которыми вы столкнетесь.