Обработка ошибок в 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")...