ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:20.79 GB of 70.42 GB (29.53%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ lib/ python2.6/ dist-packages/ zope/ interface/ - drwxr-xr-x

Directory:
Viewing file:     human.ru.txt (10.43 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
===============================
Использование реестра адаптеров
===============================

Данный документ содержит небольшую демонстрацию пакета ``zope.interface`` и его
реестра адаптеров. Документ рассчитывался как конкретный, но более узкий пример
того как использовать интерфейсы и адаптеры вне Zope 3.

Сначала нам необходимо импортировать пакет для работы с интерфейсами::

  >>> import zope.interface

Теперь мы разработаем интерфейс для нашего объекта - простого файла. Наш файл
будет содержать всего один атрибут - body, в котором фактически будет сохранено
содержимое файла::

  >>> class IFile(zope.interface.Interface):
  ...
  ...     body = zope.interface.Attribute(u'Содержимое файла.')
  ...

Для статистики нам часто необходимо знать размер файла. Но было бы несколько
топорно реализовывать определение размера прямо для объекта файла, т.к. размер
больше относится к мета-данным. Таким образом мы создаем еще один интерфейс для
представления размера какого-либо объекта::

  >>> class ISize(zope.interface.Interface):
  ...
  ...     def getSize():
  ...         'Return the size of an object.'
  ...

Теперь мы должны создать класс реализующий наш файл. Необходимо что бы наш
объект хранил информацию о том, что он реализует интерфейс `IFile`. Мы также
создаем атрибут с содержимым файла по умолчанию (для упрощения нашего
примера)::

  >>> class File(object):
  ...
  ...      zope.interface.implements(IFile)
  ...      body = 'foo bar'
  ...

Дальше мы создаем адаптер, который будет предоставлять интерфейс `ISize`
получая любой объект предоставляющий интерфейс `IFile`. По соглашению мы
используем атрибут `__used_for__` для указания интерфейса который как мы
ожидаем предоставляет адаптируемый объект, `IFile` в нашем случае. На самом
деле этот атрибут используется только для документирования. В случае если
адаптер используется для нескольких интерфейсов можно указать их все в виде
кортежа.

Опять же по соглашению конструктор адаптера получает один аргумент - context
(контекст). В нашем случае контекст - это экземпляр `IFile` (объект,
предоставляющий `IFile`) который используется для получения из него размера.
Так же по соглашению контекст сохраняется а адаптере в атрибуте с именем
`context`. Twisted комьюнити ссылается на контекст как на объект `original`.
Таким образом можно также дать аргументу любое подходящее имя, например
`file`::

  >>> class FileSize(object):
  ...
  ...      zope.interface.implements(ISize)
  ...      __used_for__ = IFile
  ...
  ...      def __init__(self, context):
  ...          self.context = context
  ...
  ...      def getSize(self):
  ...          return len(self.context.body)
  ...

Теперь когда мы написали наш адаптер мы должны зарегистрировать его в реестре
адаптеров, что бы его можно было запросить когда он понадобится. Здесь нет
какого-либо глобального реестра адаптеров, таким образом мы должны
самостоятельно создать для нашего примера реестр::

  >>> from zope.interface.adapter import AdapterRegistry
  >>> registry = AdapterRegistry()

Реестр содержит отображение того, что адаптер реализует на основе другого
интерфейса который предоставляет объект. Поэтому дальше мы регистрируем адаптер
который адаптирует интерфейс `IFile` к интерфейсу `ISize`. Первый аргумент к
методу `register()` реестра - это список адаптируемых интерфейсов. В нашем
случае мы имеем только один адаптируемый интерфейс - `IFile`. Список
интерфейсов имеет смысл для использования концепции мульти-адаптеров, которые
требуют нескольких оригинальных объектов для адаптации к новому интерфейсу. В
этой ситуации конструктор адаптера будет требовать новый аргумент для каждого
оригинального интерфейса.

Второй аргумент метода `register()` - это интерфейс который предоставляет
адаптер, в нашем случае `ISize`. Третий аргумент - имя адаптера. Сейчас нам не
важно имя адаптера и мы передаем его как пустую строку. Обычно имена полезны
если используются адаптеры для одинакового набора интерфейсов, но в различных
ситуациях. Последний аргумент - это класс адаптера::

  >>> registry.register([IFile], ISize, '', FileSize)

Теперь мы можем использовать реестр для запроса адаптера::

  >>> registry.lookup1(IFile, ISize, '')
  <class '__main__.FileSize'>

Попробуем более практичный пример. Создадим экземпляр `File` и создадим адаптер
использующий запрос реестра. Затем мы увидим возвращает ли адаптер корректный
размер при вызове `getSize()`::

  >>> file = File()
  >>> size = registry.lookup1(IFile, ISize, '')(file)
  >>> size.getSize()
  7

На самом деле это не очень практично, т.к. нам нужно самим передавать все
аргументы методу запроса. Существует некоторый синтаксический леденец который
позволяет нам получить экземпляр адаптера просто вызвав `ISize(file)`. Что бы
использовать эту функциональность нам понадобится добавить наш реестр к списку
adapter_hooks, который находится в модуле с адаптерами. Этот список хранит
коллекцию вызываемых объектов которые вызываются автоматически когда вызывается
IFoo(obj); их предназначение - найти адаптеры которые реализуют интерфейс для
определенного экземпляра контекста.

Необходимо реализовать свою собственную функцию для поиска адаптера; данный
пример описывает одну из простейших функций для использования с реестром, но
также можно реализовать поисковые функции которые, например, используют
кэширование, или адаптеры сохраняемые в базе. Функция поиска должна принимать
желаемый на выходе интерфейс (в нашем случае `ISize`) как первый аргумент и
контекст для адаптации (`file`) как второй. Функция должна вернуть адаптер,
т.е. экземпляр `FileSize`::

  >>> def hook(provided, object):
  ...     adapter = registry.lookup1(zope.interface.providedBy(object),
  ...                                provided, '')
  ...     return adapter(object)
  ...

Теперь мы просто добавляем нашу функцию к списку `adapter_hooks`::

  >>> from zope.interface.interface import adapter_hooks
  >>> adapter_hooks.append(hook)

Как только функция зарегистрирована мы можем использовать желаемый синтаксис::

  >>> size = ISize(file)
  >>> size.getSize()
  7

После нам нужно прибраться за собой, что бы другие получили чистый список
`adaper_hooks` после нас::

  >>> adapter_hooks.remove(hook)

Это все. Здесь намеренно отложена дискуссия об именованных и мульти-адаптерах,
т.к. данный текст рассчитан как практическое и простое введение в интерфейсы и
адаптеры Zope 3. Для более подробной информации имеет смысл прочитать
`adapter.txt` из пакета `zope.interface`, что бы получить более формальное,
справочное и полное трактование пакета. Внимание: многие жаловались, что
`adapter.txt` приводит их мозг к расплавленному состоянию!
Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ 
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2151 seconds