Почти всегда, когда я рассказываю об интерфейсах ftplib на занятиях по Python, учащиеся интересуются, для чего программист должен ука-
зывать строку RETR в методе загрузки. Это хороший вопрос: строка RETR является именем команды загрузки в протоколе FTP, но, как уже говорилось, модуль ftplib призван инкапсулировать этот протокол. Как мы увидим чуть ниже, при выгрузке на сервер также требуется указывать странную строку STOR. Это шаблонный программный код, который для начала приходится принимать на веру, но который напрашивается на этот вопрос. Вы, конечно, можете предложить свою заплатку для ftplib, но это не самый хороший совет начинающим изучать Python, а кроме того, такая заплата может нарушить работоспособность существующих сценариев (имеется причина, по которой интерфейс должен иметь такой вид).
Лучше будет ответить так: Python упрощает возможность расширения стандартных библиотечных модулей собственными интерфейсами более высокого уровня — с помощью всего лишь нескольких строк многократно используемого программного кода можно заставить интерфейс FTP в Python выглядеть так, как вы захотите. Например, можно взять и написать вспомогательные модули, обертывающие интерфейсы ftplib и скрывающие строку RETR. Если поместить эти модули в каталог, включенный в переменную окружения PYTHONPATH, они станут столь же доступными, как сам модуль ftplib, и будут автоматически использоваться в любом сценарии Python, который может быть написан в будущем. Помимо устранения необходимости в строке RETR модуль-оболочка может использовать допущения, которые упрощают операции FTP до единственного вызова функции.
Например, при наличии модуля, который инкапсулирует и упрощает ftplib, наш сценарий для загрузки и запуска файлов можно было бы сократить еще больше, что иллюстрирует сценарий в примере 11.3, в сущности состоящий из двух вызовов функций и ввода пароля, но дающий тот же результат, что и сценарий в примере 13.1.
Пример 13.3. PP4E\Internet\Ftp\getone-modular.py
#!/usr/local/bin/python
Сценарий на языке Python для загрузки медиафайла по FTP и его проигрывания. Использует getfile.py, вспомогательный модуль, инкапсулирующий этап загрузки по FTP.
import getfile
from getpass import getpass
filename = ‘monkeys.jpg’
# получить файл с помощью вспомогательного модуля getfile.getfile(file=filename,
site=’ftp.rmi.net’,
dir =’.’,
user=(‘lutz’, getpass(‘Pswd?’)), refetch=True)
# остальная часть сценария осталась без изменений
if input(‘Open file?’) in [‘Y’, ‘y’]:
from PP4E.System.Media.playfile import playfile playfile(filename)
Помимо того что в этом варианте существенно уменьшилось количество строк, основное тело этого сценария разбито на отдельные файлы, которые можно повторно использовать в других ситуациях. Если когда-либо вновь потребуется загрузить файл, достаточно импортировать существующую функцию, а не заниматься редактированием путем копирования и вставки. Операцию загрузки потребуется изменить только в одном файле, а не во всех местах, куда был скопирован шаблонный программный код; можно даже сделать так, чтобы функция getfile. getfile использовала urllib вместо ftplib, никак не затронув при этом его клиентов. Это хорошая конструкция.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011