Делаю замену файлов с бекапом, в два этапа. Первый - прохожу по реальному дереву файлов, и сохраняю структуру во вложенные словари, последний уровень (сами файлы) - в set, хранящийся по зарезервированному ключу словаря.
import os, shutil
src = "res" #from
dest = "D:/test/" #to
backup = "D:/test/backup"
def walker(src):
list = {"+files":[]} #create dict with reserved space for files
for file in os.listdir(src):
fullPath = os.path.join(src, file)
if os.path.isdir(fullPath):
list[file] = walker(fullPath) #if item is dir - move deeper
else:
list["+files"].append(file) #else add as filename
if not len(list["+files"]):#on no files in directory - remove empty item
del list["+files"]
return list
def install(tree, src, dest, backup):
for folder, data in tree.iteritems():
nextSrc = os.path.join(src, folder)
nextDest = os.path.join(dest, folder)
nextBackup = os.path.join(backup, folder)
#for files in current folder backup original and replace
if folder == "+files":
for file in data:
fileFrom = os.path.join(src, file)
fileTo = os.path.join(dest, file)
fileBackup = os.path.join(backup, file)
shutil.copyfile(fileTo, fileBackup)
shutil.copyfile(fileFrom, fileTo)
#else if this is folder - dig down
else:
install(tree[data], nextSrc, nextDest, nextBackup)
tree = walker(src)
install(tree, src, dest, backup)
print 'ok!'
Можно сделать копирование прямо в первом проходе, без построения дерева, но это мне кажется менее красивым и более громоздким решением (с учетом того что будет опция восстановления из бекапа). Ну и в любом случае, хотелось бы понять, в чем моя ошибка.