Листинг
xmlns:tal=«http://xml.zope.org/namespaces/tal»
Оператор TAL имеет имя и значение (что выражается именем и значением атрибута). Внутри значения обычно записано TAL–выражение, синтаксис которого описывается другим языком — TALES (Template Attribute Language Expression Syntax, синтаксис выражений TAL).
Таким образом, ZPT наполняет содержимым шаблоны, интерпретируя атрибуты TAL. Например, чтобы Zope подставил название документа (тег TITLE), шаблон может иметь следующий код:
Листинг
<title tal:content=«here/title»>Doc Title</title>
Стоит заметить, что приведенный код сойдет за код на HTML, то есть, Web–дизайнер может на любом этапе работы над проектом редактировать шаблон в HTML–редакторе (при условии, что тот сохраняет незнакомые атрибуты из пространства имен tal). В этом примере here/titleявляется выражением TALES. Текст Doc Title служит ориентиром для web–дизайнера и заменяется значением выражения here/title, то есть, будет взято свойство title документа Zope.
Примечание:
В Zope объекты имеют свойства. Набор свойств зависит от типа объекта, но может быть расширен в индивидуальном порядке. Свойство id присутствует всегда, свойство title обычно тоже указывается.
В качестве более сложного примера можно рассмотреть организацию повтора внутри шаблона (для опробования этого примера в Zope нужно добавить объект Page Template):
Листинг
<ul>
<li tal:define=«s modules/string»
tal:repeat=«el python:s.digits»>
<a href=«DUMMY»
tal:attributes=«href string:/digit/$el»
tal:content=«el»>SELECTION</a>
</li>
</ul>
Этот шаблон породит следующий результат:
Листинг
<ul>
<li><a href="/digit/0»>0</a></li>
<li><a href="/digit/1»>1</a></li>
<li><a href="/digit/2»>2</a></li>
<li><a href="/digit/3»>3</a></li>
<li><a href="/digit/4»>4</a></li>
<li><a href="/digit/5»>5</a></li>
<li><a href="/digit/6»>6</a></li>
<li><a href="/digit/7»>7</a></li>
<li><a href="/digit/8»>8</a></li>
<li><a href="/digit/9»>9</a></li>
</ul>
Здесь нужно обратить внимание на два основных момента:
в шаблоне можно использовать выражения Python (в данном примере переменная s определена как модуль Python) и переменную–счетчик цикла el, которая проходит итерации по строке string.digits.
с помощью TAL можно задавать не только содержимое элемента, но и атрибута тега (в данном примере использовался атрибут href).
Детали можно узнать по документации. Стоит лишь заметить, что итерация может происходить по самым разным источникам данных: содержимому текущей папки, выборке из базы данных или, как в приведенном примере, по объекту Python.
Любой программист знает, что программирование тем эффективнее, чем лучше удалось «расставить скобки», выведя «общий множитель за скобки». Другими словами, хорошие программисты должны быть достаточно «ленивы», чтобы найти оптимальную декомпозицию решаемой задачи. При проектировании динамического web–сайта Zope позволяет разместить «множители» и «скобки» так, чтобы достигнуть максимального повторного использования кода (как разметки, так и сценариев). Помогает этому уникальный подход к построению взаимоотношений между объектами: заимствование (acquisition).
Пусть некоторый объект (документ, изображение, сценарий, подключение к базе данных и т.п.) расположен в папке Example. Теперь объекты этой папки доступны по имени из любых нижележащих папок. Даже политики безопасности заимствуются более глубоко вложенными папками от папок, которые ближе к корню. Заимствование является очень важной концепцией Zope, без понимания которой Zope сложно грамотно применять, и наоборот, ее понимание позволяет экономить силы и время, повторно используя объекты в разработке.
Самое интересное, что заимствовать объекты можно также из параллельных папок. Пусть, например, рядом с папкой Example находится папка Zigzag, в которой лежит нужный объект (его наименование note). При этом в папке Example программиста интересует объект index_html, внутри которого вызывается note. Обычный путь к объекту index_html будет происходить по URI вроде http://zopeserver/Example/. А вот если нужно использовать note из Zigzag (и в папке Example его нет), то URI будет: http://zopeserver/Zigzag/Example/. Таким образом, указание пути в Zope отличается от традиционного пути, скажем, в Unix: в пути могут присутствовать «зигзаги» через параллельные папки, дающие возможность заимствовать объекты из этих папок. Таким образом, можно сделать конкретную страницу, комбинируя один или несколько независимых аспектов.
Заключение
В этой лекции были рассмотрены различные подходы к использованию Python в web–приложениях. Самый простой способ реализации web–приложения — использование CGI–сценариев. Более сложным является использование специальных модулей для web–сервера, таких как mod_python. Наконец, существуют технологии вроде Zope, которые предоставляют специализированные сервисы, позволяющие создавать web–приложения.
9. Лекция: Сетевые приложения на Python.
В этой лекции рассматривается реализация на Python простейшего клиент–серверного приложения, дается представление о типичном для сети Internet приложении. Стандартная библиотека Python имеет несколько модулей для работы с различными протоколами. Этими модулями охватываются как низкоуровневые протоколы (TCP/IP, UDP/IP), так и высокоуровневые (HTTP, FTP, SMTP, POP3, IMAP, NNTP, …). Здесь будет рассмотрена работа с сокетами (модуль socket) и три модуля высокоуровневых протоколов (urllib2, poplib, smtplib). При этом предполагается, что имеется понимание принципов работы IP–сети и некоторых ее сервисов, а также представление о системе WWW.
Работа с сокетами
Применяемая в IP–сетях архитектура клиент–сервер использует IP–пакеты для коммуникации между клиентом и сервером. Клиент отправляет запрос серверу, на который тот отвечает. В случае с TCP/IP между клиентом и сервером устанавливается соединение (обычно с двусторонней передачей данных), а в случае с UDP/IP — клиент и сервер обмениваются пакетами (дейтаграммамми) с негарантированной доставкой.
Каждый сетевой интерфейс IP–сети имеет уникальный в этой сети адрес (IP–адрес). Упрощенно можно считать, что каждый компьютер в сети Интернет имеет собственный IP–адрес. При этом в рамках одного сетевого интерфейса может быть несколько сетевых портов. Для установления сетевого соединения приложение клиента должно выбрать свободный порт и установить соединение с серверным приложением, которое слушает (listen) порт с определенным номером на удаленном сетевом интерфейсе. Пара IP–адрес и порт характеризуют сокет (гнездо) - начальную (конечную) точку сетевой коммуникации. Для создания соединения TCP/IP необходимо два сокета: один на локальной машине, а другой — на удаленной. Таким образом, каждое сетевое соединение имеет IP–адрес и порт на локальной машине, а также IP–адрес и порт на удаленной машине.
Модуль socket обеспечивает возможность работать с сокетами из Python. Сокеты используют транспортный уровень согласно семиуровневой модели OSI (Open Systems Interconnection, взаимодействие открытых систем), то есть относятся к более низкому уровню, чем большинство описываемых в этом разделе протоколов.
Уровни модели OSI:
Физический
Поток битов, передаваемых по физической линии. Определяет параметры физической линии.
Канальный (Ethernet, PPP, ATM и т.п.)
Кодирует и декодирует данные в виде потока битов, справляясь с ошибками, возникающими на физическом уровне в пределах физически единой сети.