реклама
Бургер менюБургер меню

Кеннет Рейтц – Автостопом по Python (страница 32)

18

Этот выбор позволяет пользователю изменять объекты, но они становятся гораздо читабельнее, а дополнительная работа, выполняемая внутри PreparedRequest, позволяет исправить проблемы с регистром и использовать словарь вместо CookieJar (ищите оператор if isinstance()/else):

#

#… из файла models.py…

#

class PreparedRequest():

····#

····#…пропускаем все остальное…

····#

····def prepare_cookies(self, cookies):

········"""Подготавливает данные заданного HTTP cookie.

········Эта функция в итоге генерирует заголовок ''Cookie'' на основе

········предоставленных cookies с использованием cookielib. Из-за особенностей

········дизайна cookielib заголовок не будет сгенерирован повторно,

········если он уже существует. Это значит, что эта функция может быть

········вызвана всего один раз во время жизни объекта

········:class:'PreparedRequest <PreparedRequest>'. Любые последующие вызовы

········''prepare_cookies'' не возымеют эффекта, если только заголовок "Cookie"

········не будет удален заранее."""

········if isinstance(cookies, cookielib.CookieJar):

············self._cookies = cookies

········else:

············self._cookies = cookiejar_from_dict(cookies)

········cookie_header = get_cookie_header(self._cookies, self)

········if cookie_header is not None:

············self.headers['Cookie'] = cookie_header

Эти детали могут показаться незначительными, но они позволяют создать интуитивно понятный API.

Примеры из стиля Requests

Примеры стиля из Requests демонстрируют использование множеств (по нашему мнению, о них незаслуженно забывают!), мы также взглянем на модуль requests.status_codes module — он задействуется для упрощения стиля остального кода и позволяет избежать применения жестко закодированных кодов состояния HTTP в остальных местах.

Мы еще не приводили пример использования множеств в Python. Множества в Python ведут себя так же, как и множества в математике: вы можете выполнить операции вычитания, объединения (с помощью оператора ИЛИ) и пересечения (с помощью оператора И):

>>> s1 = set((7,6))

>>> s2 = set((8,7))

>>> s1

{6, 7}

>>> s2

{8, 7}

>>> s1 — s2 # разность множеств

{6}

>>> s1 | s2 # объединение множеств

{8, 6, 7}

>>> s1 & s2 # пересечение множеств

{7}

Рассмотрим пример работы с множествами, вы можете найти его в конце этой функции из файла cookies.py (рядом с пометкой ):

Спецификация **kwargs позволяет пользователю предоставить любой параметр с ключевым словом для cookie (или не предоставлять их вовсе).

Арифметика множеств! Питонская. Простая. Доступная в стандартной библиотеке. Для словаря функция set() формирует множество ключей.

Это отличный пример того, что разбиение длинной строки на две короткие более разумно. Дополнительная переменная err не нанесла никакого вреда.

Вызов result.update(kwargs) обновляет словарь result парами ключ/значение, содержащимися в словаре kwargs, заменяя существующие пары или создавая те пары, которых не было.

Здесь вызов метода bool() возвращает значение True, если объект верен (это значит, что его значение оценивается как True — в данном случае вызов bool(result['port']) оценивается как True, если значение не равно None и не является пустым контейнером).

Сигнатура для инициализации cookielib.Cookie представляет собой набор из 18 позиционных аргументов и одного аргумента с ключевым словом (rfc2109 по умолчанию считается равным False). Нам, как среднестатистическим пользователям, невозможно запомнить все значения и их позиции, поэтому Requests позволяет присваивать значения позиционным аргументам, основываясь на их имени, как в случае аргументов с ключевым словом, отправляя целый словарь.

Файл status_codes.py нужен только для того, чтобы создать объект, который может искать коды состояний по атрибуту. Мы сначала покажем определение словаря в файле status_codes.py, а затем — фрагмент кода файла sessions.py, в котором словарь используется.

Все эти варианты состояния OK станут ключами словаря. За исключением счастливого человека (\\o/) и флажка ().

Устаревшие значения расположены на отдельной строке, поэтому, когда их в будущем удалят, в системе контроля версий это будет четко определено.

LookupDict позволяет получать доступ к своим элементам через точку, как это показано в следующей строке.

codes.ok == 200 и codes.okay == 200.

А также codes.OK == 200 и codes.OKAY == 200.

Вся эта работа нужна для того, чтобы создать словарь с кодами состояний. Для чего? Использование словаря вместо цифр на протяжении всего кода (что чревато опечатками) позволяет повысить читаемость, а также хранить все эти числа в одном файле. Поскольку все числа, представляющие коды, записаны в словарь, каждое из них появится всего один раз. Вероятность опечаток при этом значительно снижается.

Преобразование ключей в атрибуты вместо их использования в качестве строк в словаре также снижает риск опечаток. Рассмотрим пример кода из файла sessions.py, который гораздо легче прочитать, когда в нем используются слова, а не числа.

Здесь импортируются коды состояний.

Классы-примеси мы опишем в пункте «Примеси (еще одна отличная штука)» подраздела «Примеры структуры из Werkzeug» следующего раздела. Примесь предоставляет методы перенаправления для основного класса Session, который определен в том же файле, но не показан в приведенном фрагменте.

Мы входим в цикл, который следует за перенаправлениями и позволяет нам получить желаемое содержимое. Вся логика цикла удалена из этого фрагмента для краткости.

Коды состояний, представленные в виде текста, гораздо читабельнее, нежели числа (которые трудно запомнить): codes.see_other в противном случае выглядел бы как 303.

codes.found выглядел бы как 302, а codes.moved — как 301. Поэтому код становится самозадокументированным; мы можем узнать значение переменных из их имен. Мы избежали засорения кода опечатками, добавив точечную нотацию вместо словаря и строк (например, codes.found вместо codes["found"]).

Werkzeug

Для того чтобы прочесть код Werkzeug, нам нужно узнать, как веб-серверы общаются с приложениями. В следующих абзацах мы попытались представить максимально короткий обзор по этому вопросу.

Интерфейс Python для взаимодействия серверов с веб-приложениями определен в PEP 333, который написан Филипом Джей Эби (Phillip J. Eby) в 2003 году[68]. В нем указано, как веб-сервер (вроде Apache) общается с приложением Python или фреймворком.

1. Сервер будет вызывать приложение каждый раз при получении запроса HTTP (например, GET или POST).