Обработка ошибок в Python

Мне нужно создать программу, которая будет загружать файлы с FTP-сервера, архивировать их и загружать в папку загрузки на FTP-сервере. Мой старый код хорош, но мой инструктор попросил, чтобы я организовал свой код в логические функции, и после организации моего кода он не запустился. Это старый код, который отлично работает:

import os
import upload
import download
import zipfile
import ConfigParser
import ftputil
import shutil
import time


def main():

    #create a folder Temp on drive D:\ for later use
    path = r'D:\Temp'
    os.makedirs(path)

    #parse all the  values at configuration file named config.ini
    config = ConfigParser.ConfigParser()
    config.readfp(open('config.ini'))
    server = config.get('main', 'Server')
    username = config.get('main', 'Username')
    password = config.get('main', 'Password')
    uploads = config.get('main', 'Upload folder')
    downloads = config.get('main', 'Download folder')

    #connect to ftp
    ftp = ftputil.FTPHost(server, username, password)

    dirlist = ftp.listdir(downloads)

    #download all files from download folder to the created temp folder
    for list in dirlist:
        ftp.chdir(downloads)
        target = os.path.join(path, list)
        ftp.download(list, target)

    #zipping files
    absolute_path = r'D:\Temp'
    dirlist = os.listdir(absolute_path)
    filepath = r'D:\Temp\part2b.zip'
    zip_name = zipfile.ZipFile(filepath, 'w')
    for list in dirlist:
        get_file = os.path.join(absolute_path, list)
        zip_name.write(get_file, 'part2b\\' + list)

    #upload the zipfile named project2.zip to upload folder at ftp
    ftp.chdir(uploads)
    ftp.upload(filepath, uploads + '/part2b.zip')
    ftp.close()

#close the zipfile to remove the temp folder
    zip_name.close()

    #message
    print "Successfully uploaded all files in the upload folder"
    print ""
    print "this will close in 5 seconds....."


#delete temp folder
    shutil.rmtree(path, 'true')
    time.sleep(5)


if __name__ == '__main__':
    main()

И это новый упорядоченный код, но он не работает должным образом, но когда я пробую все функции в командной строке python, это хорошо. Я не знаю, в чем здесь проблема:

import os
import zipfile
import ConfigParser
import ftputil
import shutil
import time
import tempfile



def dl_function(source_folder, target_folder):
    dirlist = ftp.listdir(source_folder)
    for list in dirlist:
        source = os.path.join(source_folder, list)
        target = os.path.join(target_folder, list)
        ftp.download(source, target)

def zip_function(temp_folder):
    dirlist = os.listdir(temp_folder)
    filepath = os.path.join(temp_folder, 'project2b.zip')
    zip_name = zipfile.ZipFile(filepath, 'w')
    for list in dirlist:
        get_file = os.path.join(temp_folder, list)
        zip_name.write(get_file, 'part2b\\' + list)

def upload_function(target_folder):
    ftp.upload(filepath, target_folder + '/part2b.zip')


def main():

    temp_folder = tempfile.mkdtemp()

    #parse all the  values at configuration file named config.ini
    config = ConfigParser.ConfigParser()
    config.read(open('config.ini'))
    server = config.get('main', 'Server')
    username = config.get('main', 'Username')
    password = config.get('main', 'Password')
    uploads = config.get('main', 'Upload folder')
    downloads = config.get('main', 'Download folder')

    ftp = ftputil.FTPHost(server, username, password)

    try:

        dl_function(downloads, temp_folder)
        zip_function(temp_folder)
        upload_function(uploads)

    finally:
        ftp.close() 
        zip_name.close()        

    print "This will close in 5 seconds"

    #delete temp folder
    shutil.rmtree(temp_folder, 'true')
    time.sleep(5)

if __name__ == '__main__':
    main()

2 ответа

Решение

Это фантастический пример того, как вы должны использовать логирование в вашем приложении. Обычно, когда что-то взрывается, вы можете отладить его двумя способами

  • Прикрепить отладчик
  • Посмотрите на некоторые подробные записи

Последний вариант больше подходит для развернутого кода, поскольку отладчик не всегда удобен.

Посмотрите информацию о регистрации на странице pydocs. Для вашего кода добавьте:-

import os
import zipfile
import ConfigParser
import ftputil
import shutil
import time
import tempfile
import logging



def dl_function(source_folder, target_folder):
    logging.trace("Running dl_function")
    dirlist = ftp.listdir(source_folder)
    logging.trace("Got a dirlist")
    for list in dirlist:
        logging.trace("Running running for item " + list + " in dirlist")
        source = os.path.join(source_folder, list)
        logging.trace("Setting source to " + source)
        target = os.path.join(target_folder, list)
        logging.trace("Setting target to " + source)
        logging.trace("Attempting FTP download from " + source + " to " + target)
        ftp.download(source, target)
        logging.info("File downloaded from FTP")

...
...
...

if __name__ == '__main__':
    logging.info("Starting downloading application")
    main()

Самая важная часть ведения журнала - это правильное разделение записи, поэтому вы используете правильные уровни (Debug, Info, Warning, Error, Critical). На странице pydocs есть руководство.

Просматривая выходные данные журналов, вы можете увидеть, как далеко продвигается ваша программа в процессе ее выполнения и где она умирает, и сузить ее до одной или двух строк.

Ваш upload_function а также dl_function оба пытаются использовать неопределенные переменные (ftp а также filepath в upload_function а также ftp в dl_function).

У вас также есть zip_name.close() позвонить в, наконец, блок в main это должно действительно принадлежать zip_function (для этого потребуется собственный блок try / finally).

wrt / сообщение об ошибке, вы должны запустить скрипт из окна командной строки, чтобы увидеть все трассировку и сообщение об ошибке.

Абсолютно не связано, но ваше именование может быть улучшено (то есть "download_files" вместо "dl_function")...

Другие вопросы по тегам