Читаем Автостопом по Python онлайн бесплатно
В Werkzeug методы класса-примеси иногда могут требовать наличия определенных атрибутов. Эти требования зачастую приводятся в строке документации класса-примеси.
В классе UserAgentMixin нет ничего особенного; он создает подкласс объекта, что выполняется по умолчанию в Python 3 и настоятельно рекомендуется для совместимости с Python 2. Все это нужно делать явно, поскольку «явное лучше, чем неявное».
UserAgentMixin.user_agent предполагает, что существует атрибут self.environ.
При включении в список базовых классов для Request предоставляемый им атрибут становится доступным с помощью вызова Request(environ). user_agent.
Больше ничего нет — мы полностью рассмотрели определение класса Request. Вся функциональность предоставляется базовым классом или классами-примесями. Модульными, подключаемыми и такими же великолепными, как Форд Префект.
Базовый класс object добавляет атрибуты по умолчанию, на которые полагаются другие встроенные параметры. Классы, которые не наследуют от класса object, называются старыми или классическими классами. В Python 3 таких классов нет, наследование от класса object выполняется по умолчанию. Это означает, что все классы Python 3 являются новыми. Новые классы доступны в Python 2.7 (их поведение не изменялось с версии Python 2.3), но наследование должно быть прописано явно, и мы считаем, что так нужно делать всегда.
Более подробная информация содержится в документации к Python для новых классов (https://www.python.org/doc/newstyle/), в руководстве по адресу http://www.python-course.eu/classes_and_type.php, а история их создания — в статье по адресу http://tinyurl.com/history-new-style-classes. Рассмотрим некоторые различия между старыми и новыми классами (в Python 2.7; все классы Python 3 являются новыми):
>>> class A(object):
… ····"""Новый класс, он является подклассом object."""
…
>>> class B:
… ····"""Старый класс."""
…
>>> dir(A)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__']
>>>
>>> dir(B)
['__doc__', '__module__']
>>>
>>> type(A)
>>> type(B)
>>>
>>> import sys
>>> sys.getsizeof(A()) # размер в байтах.
64
>>> sys.getsizeof(B())
72
Flask — это веб-микрофреймворк, который объединяет Werkzeug и Jinja2, оба они написаны Армином Роначером (Armin Ronacher). Создавался шутки ради и был выпущен 1 апреля 2010 года, но быстро стал одним из самых популярных фреймворков Python. Армин несколькими годами ранее (в 2007 году) выпустил Werkzeug, преподнеся его как «швейцарский нож для веб-разработки на Python», и (как мы предполагаем) был немного расстроен тем, что он приживался слишком медленно. Идея Werkzeug заключалась в том, чтобы отвязать WSGI от всего остального, дабы разработчики могли подключать вспомогательные программы по своему выбору. Армин еще не догадывался, насколько нам нужны дополнительные «рельсы»[71].
Программный фреймворк похож на физический фреймворк — предлагает структуру для создания приложения WSGI[72]: пользователь библиотеки предоставляет компоненты, которые основное приложение Flask запускает. Наша цель при чтении кода — понять структуру фреймворка и его возможности.
Получаем Flask с GitHub:
$ git clone https://github.com/pallets/flask.git




