У вас есть пара проблем в вашем коде.
Сначала chkifexists
начинает return
, как только находит существующий файл, поэтому никогда не проверяет оставшиеся имена; Кроме того, если файлы не найдены, то hashcolumn и filepathNum никогда не устанавливаются, что дает вам UnboundLocalError
.
Во-вторых, вы звоните chkifexists
в двух местах - с removedupes
и с CleanAndPrettify
. Так что removedupes
будет работать для каждого существующего файла для каждого существующего файла - не то, что вы хотите! Фактически, поскольку CleanAndPrettify
только что проверил, что файл существует, removedupes
должен просто идти с тем, что ему передано.
Существует как минимум три способа обработки случая, когда файлы не найдены: chkifexists
вызвать исключение; в CleanAndPrettify
есть флаг, который отслеживает, были ли найдены файлы; или превратите результаты chkifexists
в list
, которые затем можно проверить на пустоту.
В измененном коде я переместил файлы в словарь с именем в качестве ключа и значением в виде кортежа hashcolumn
и filepathNum
. chkifexists
теперь принимает имена файлов для поиска в качестве словаря и yield
s значения, когда файл найден; если файлы не найдены, будет сгенерировано исключение NoFilesFound
.
Вот код:
import os, csv
# store file attributes for easy modifications
# format is 'filename': (hashcolumn, filepathNum)
files = {
'A.csv': (7, 5),
'B.csv': (15, 5),
'C.csv': (1, 0),
}
class NoFilesFound(Exception):
"No .csv files were found to clean up"
def chkifexists(somefiles):
# load all three at once, but only yield them if filename
# is found
filesfound = False
for fname, (hashcolumn, filepathNum) in somefiles.items():
if os.path.isfile(fname):
filesfound = True
yield fname, hashcolumn, filepathNum
if not filesfound:
raise NoFilesFound
def removedupes(infile, outfile, hashcolumn, filepathNum):
# this is now a single-run function
r1 = file(infile, 'rb')
r2 = csv.reader(r1)
w1 = file(outfile, 'wb')
w2 = csv.writer(w1)
hashes = set()
for row in r2:
if row[hashcolumn] =="":
w2.writerow(row)
hashes.add(row[hashcolumn])
if row[hashcolumn] not in hashes:
w2.writerow(row)
hashes.add(row[hashcolumn])
w1.close()
r1.close()
def bakcount(origfile1, origfile2):
'''This function creates a .bak file of the original and does a row count
to determine the number of rows removed'''
os.rename(origfile1, origfile1+".bak")
count1 = len(open(origfile1+".bak").readlines())
#print count1
os.rename(origfile2, origfile1)
count2 = len(open(origfile1).readlines())
#print count2
print str(count1 - count2) + " duplicate rows removed from " \
+ str(origfile1) +"!"
def CleanAndPrettify():
print "Removing duplicate rows from input files..."
try:
for fname, hashcolumn, filepathNum in chkifexists(files):
removedupes(
fname,
os.path.splitext(fname)[0] + "2.csv",
hashcolumn,
filepathNum,
)
bakcount (fname, os.path.splitext(fname)[0] + "2.csv")
except NoFilesFound:
print "no files to clean up"
CleanAndPrettify()
Невозможно проверить, так как у меня нет файлов A
, B
и C
.csv, но, надеюсь, это укажет вам правильное направление. Как видите, опция raise NoFilesFound
использует метод flag для отслеживания файлов, которые не были найдены; вот метод list
:
def chkifexists(somefiles):
# load all three at once, but only yield them if filename
# is found
for fname, (hashcolumn, filepathNum) in somefiles.items():
if os.path.isfile(fname):
filesfound = True
yield fname, hashcolumn, filepathNum
def CleanAndPrettify():
print "Removing duplicate rows from input files..."
found_files = list(chkifexists(files))
if not found_files:
print "no files to clean up"
else:
for fname, hashcolumn, filepathNum in found_files:
removedupes(...)
bakcount(...)