Страницы

Поиск по вопросам

понедельник, 3 июня 2019 г.

Помогите исправить ошибку в примере из книги Лутца

Учусь по книге Лутца «программирование на python», но в одном из сценариев никак не могу решить проблему. Собственно код сценария:
import sys, os maxfileload = 1000000 blocksize = 1024 * 500
def copyfile(pathFrom, pathTo, maxfileload=maxfileload): """ Копирует один файл из pathFrom в pathTo, используя двоичный режим для подавления операций кодирования/декодирования символов """ if os.path.getsize(pathFrom) <= maxfileload: bytesFrom = open(pathFrom, 'rb').read() # маленькие файлы читать целиком open(pathTo, 'wb').write(bytesFrom) else: fileFrom = open(pathFrom, 'rb') # открыть файл для чтения в двоичном режиме fileTo = open(pathTo, 'wb') # открыть файл для записи в двоичном режиме while True: bytesFrom = fileFrom.read(blocksize) # читать по одному блоку if not bytesFrom: break # если последний блок пуст fileTo.write(bytesFrom) # записать один блок
def copytree(dirFrom, dirTo, verbose = 0): """ Копирует содержимое каталогов и подкаталогов из dirFrom в dirTo, и возвращает счетчик (files, dirs) """ fcount = dcount = 0 for filename in os.listdir(dirFrom): pathFrom = os.path.join(dirFrom, filename) pathTo = os.path.join(dirTo, filename) if not os.path.isdir(pathFrom): try: if verbose > 1: print('copying', pathFrom, 'to', pathTo) copyfile(pathFrom, pathTo) fcount += 1 except: print('Error copying', pathFrom, 'to', pathTo, '--akipped') print(sys.exc_info()[0], sys.exc_info()[1]) else: if verbose: print('copying dir', pathFrom, 'to', pathTo) try: os.mkdir(pathTo) below = copytree(pathFrom, pathTo) fcount += below[0] dcount += below[1] dcount += 1 except: print('Error creating', pathTo, '--skipped') print(sys.exc_info()[0], sys.exc_info()[1]) return(fcount, dcount)
def getargs(): """ Извлекает и проверяет аргументы с именами каталогов, по умолчанию возвращает None в случае ошибки """ try: dirFrom, dirTo = sys.argv[1:] except: print('Usage error: cpall.py dirFrom dirTo') else: if not os.path.isdir(dirFrom): print('Error: dirFrom is not a directory') elif not os.path.isdir(dirTo): os.mkdir(dirTo) print('Note: dirTo created') return(dirFrom, dirTo) else: print('Warning: dirTo already exists') if hasattr(os.path, 'samefile'): same = os.path.samefile(dirFrom, dirTo) else: same = os.path.abspath(dirFrom) == os.path.abspath(dirTo) if same: print('Error: dirFrom same as dirTo') else: return(dirFrom, dirTo)
if __name__ == '__main__': import time dirstuple = getargs() if dirstuple: print('Copying...') start = time.clock() fcount, dcount = copytree(*dirstuple) print('Copied', fcount, 'files', dcount, 'directories', end=' ') print('in', time.clock() - start, 'seconds')
При запуске сценария не копируются подкаталоги и файлы в них, а для файлов на верхнем уровне заданного каталога (pathFrom) выдает исключение FileExistsError. Несколько раз проверял сценарий, но никак не могу понять в чем проблема.
Вывод при исполнении скрипта:
C:\Python34\src\lutz_ex>cpall.py C:\Python34\src\lutz_ex C:\temp Warning: dirTo already exists Copying... Error creating C:\temp\bigext_tree.py --skipped [WinError 183] Невозможно создать файл, так как он уже существует: 'C:\\temp\\bigext_tree.py' Copied 11 files 0 directories in 0.02591993545451741 seconds


Ответ

У вас в функции copytree стоит проверка if not os.path.isdir(pathFrom) при переборе объектов для копирования. Соответственно, когда очередь доходит до подкаталогов, то они пропускаются, поскольку являются каталогами и не проходят проверку в if
По поводу FileExistsError. После успешного копирования файла в блоке
if not os.path.isdir(pathFrom): try: if verbose > 1: print('copying', pathFrom, 'to', pathTo) copyfile(pathFrom, pathTo) fcount += 1
у нас не вызывает except, соответственно мы переходим к блоку else
else: if verbose: print('copying dir', pathFrom, 'to', pathTo) try: os.mkdir(pathTo) below = copytree(pathFrom, pathTo) fcount += below[0] dcount += below[1] dcount += 1 except: print('Error creating', pathTo, '--skipped') print(sys.exc_info()[0], sys.exc_info()[1])
где мы в блоке try мы пытаемся вызвать os.mkdir(pathTo), что невозможно сделать, поскольку pathTo уже существует

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

Отправить комментарий