Страницы

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

пятница, 13 марта 2020 г.

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

#python


Учусь по книге Лутца «программирование на 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

    


Ответы

Ответ 1



У вас в функции 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 уже существует

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

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