Heray-Was-Here
Server : nginx/1.14.1
System : Linux hwsrv-1092325.hostwindsdns.com 4.18.0-553.5.1.el8.x86_64 #1 SMP Tue May 21 05:46:01 UTC 2024 x86_64
User : nginx ( 993)
PHP Version : 7.4.33
Disable Function : NONE
Directory :  /usr/share/doc/python3-zope-interface/docs/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/doc/python3-zope-interface/docs/adapter.ru.rst
================
РССстр Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ²
================

.. contents::

РССстры Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ для рСгистрации ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅
зависят ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠΉ, ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спСцификаций интСрфСйсов ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚
(Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ) ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ интСрфСйс. Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅, рСгистрации ΠΈΠΌΠ΅ΡŽΡ‚
ΠΈΠΌΠ΅Π½Π°. (МоТно Π΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎΠ± ΠΈΠΌΠ΅Π½Π°Ρ… ΠΊΠ°ΠΊ ΠΎ спСцификаторах прСдоставляСмого
интСрфСйса.)

Π’Π΅Ρ€ΠΌΠΈΠ½ "спСцификация интСрфСйса" ссылаСтся ΠΈ Π½Π° интСрфСйсы ΠΈ Π½Π° опрСдСлСния
интСрфСйсов, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ опрСдСлСния интСрфСйсов Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ классом.

ΠžΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Π΅ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹
==================

Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Π΅Π΄ΠΈΠ½ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡƒΡŽ
ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ::

  >>> from zope.interface.adapter import AdapterRegistry
  >>> import zope.interface

  >>> class IR1(zope.interface.Interface):
  ...     pass
  >>> class IP1(zope.interface.Interface):
  ...     pass
  >>> class IP2(IP1):
  ...     pass

  >>> registry = AdapterRegistry()

ΠœΡ‹ зарСгистрируСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ зависит ΠΎΡ‚ IR1 ΠΈ "прСдоставляСт" IP2::

  >>> registry.register([IR1], IP2, '', 12)

ПослС рСгистрации ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ снова::

  >>> registry.lookup([IR1], IP2, '')
  12

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ†Π΅Π»ΠΎΠ΅ Π² этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅. Π’ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… прилоТСниях Π²Ρ‹
ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π° самом Π΄Π΅Π»Π΅ зависят ΠΈΠ»ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚
интСрфСйсы. РССстр Π½Π΅ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ рСгистрируСтся ΠΈ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΡ‹
ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ†Π΅Π»Ρ‹Π΅, ΠΈΠ»ΠΈ строки Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ наши ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹. Π—Π΄Π΅ΡΡŒ Π΅ΡΡ‚ΡŒ
ΠΎΠ΄Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. РСгистрация значСния None удаляСт Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ для любого
зарСгистрированного ΠΏΡ€Π΅ΠΆΠ΄Π΅ значСния.

Если ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ зависит ΠΎΡ‚ спСцификации ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
спСцификации которая Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠ½ зависит::

  >>> class IR2(IR1):
  ...     pass
  >>> registry.lookup([IR2], IP2, '')
  12

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ класс Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ для запроса ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°::

  >>> class C2:
  ...     zope.interface.implements(IR2)

  >>> registry.lookup([zope.interface.implementedBy(C2)], IP2, '')
  12

ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½ для интСрфСйсов ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ прСдоставляСмый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ
интСрфСйс Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚::

  >>> registry.lookup([IR1], IP1, '')
  12
  >>> registry.lookup([IR2], IP1, '')
  12

Но Ссли Π²Ρ‹ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚Π΅ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ которая Π½Π΅ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ
зависит ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π²Ρ‹ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½ΠΈΡ‡Π΅Π³ΠΎ::

  >>> registry.lookup([zope.interface.Interface], IP1, '')

ΠœΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€ΠΎΡ‡ΠΈΠΌ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΏΡ€ΠΈ запросС::

  >>> registry.lookup([zope.interface.Interface], IP1, '', 42)
  42

Если Π²Ρ‹ ΠΏΡ€ΠΎΠ±ΡƒΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ интСрфСйс ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ прСдоставляСт Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅
Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½ΠΈΡ‡Π΅Π³ΠΎ::

  >>> class IP3(IP2):
  ...     pass
  >>> registry.lookup([IR1], IP3, '')

Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½ΠΈΡ‡Π΅Π³ΠΎ Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π½Π΅Π²Π΅Ρ€Π½ΠΎΠ΅ имя::

  >>> registry.lookup([IR1], IP1, 'bob')
  >>> registry.register([IR1], IP2, 'bob', "Bob's 12")
  >>> registry.lookup([IR1], IP1, 'bob')
  "Bob's 12"

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ имя ΠΏΡ€ΠΈ запросС::

  >>> registry.lookup([IR1], IP1)
  12

Если ΠΌΡ‹ рСгистрируСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдоставляСт IP1::

  >>> registry.register([IR1], IP1, '', 11)

Ρ‚ΠΎΠ³Π΄Π° этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ прСимущСство ΠΏΠ΅Ρ€Π΅Π΄ O(12)::

  >>> registry.lookup([IR1], IP1, '')
  11

Π’Π°ΠΊΠΆΠ΅, Ссли ΠΌΡ‹ рСгистрируСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ для IR2 Ρ‚ΠΎΠ³Π΄Π° ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ прСимущСство
ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ IR2::

  >>> registry.register([IR2], IP1, '', 21)
  >>> registry.lookup([IR2], IP1, '')
  21

Поиск Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ (Ссли Π²ΠΎΠΎΠ±Ρ‰Π΅ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ) зарСгистрировано
-----------------------------------------------------

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ Π΅ΡΡ‚ΡŒ-Π»ΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ зарСгистрированный для Π½Π°Π±ΠΎΡ€Π° интСрфСйсов.
Π­Ρ‚ΠΎ отличаСтся ΠΎΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ запроса Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ здСсь ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ совпадСниС::

  >>> print registry.registered([IR1], IP1)
  11

  >>> print registry.registered([IR1], IP2)
  12

  >>> print registry.registered([IR1], IP2, 'bob')
  Bob's 12
  

  >>> print registry.registered([IR2], IP1)
  21

  >>> print registry.registered([IR2], IP2)
  None

Π’ послСднСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, None Π±Ρ‹Π» Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ для Π΄Π°Π½Π½ΠΎΠ³ΠΎ интСрфСйса
Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π±Ρ‹Π»ΠΎ зарСгистрировано.

lookup1
-------

Запрос ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° - это Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ частая опСрация ΠΈ для Π½Π΅Π΅ Π΅ΡΡ‚ΡŒ
спСциализированная вСрсия запроса которая ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½Π° Π²Ρ…ΠΎΠ΄ СдинствСнный
Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ интСрфСйс::

  >>> registry.lookup1(IR2, IP1, '')
  21
  >>> registry.lookup1(IR2, IP1)
  21

Адаптация Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅
---------------------

РССстр Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π°Π΄Π°ΠΏΡ‚Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ интСрфСйс адаптируСтся ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚
Π΄Ρ€ΡƒΠ³ΠΎΠΉ интСрфСйс. РССстр Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ вычислСниС Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ². Π’
этом случаС ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ для Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ²::

   >>> class IR(zope.interface.Interface):
   ...     pass

   >>> class X:
   ...     zope.interface.implements(IR)
           
   >>> class Y:
   ...     zope.interface.implements(IP1)
   ...     def __init__(self, context):
   ...         self.context = context

  >>> registry.register([IR], IP1, '', Y)

Π’ этом случаС ΠΌΡ‹ рСгистрируСм класс ΠΊΠ°ΠΊ Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ
`queryAdapter` для получСния Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°::

  >>> x = X()
  >>> y = registry.queryAdapter(x, IP1)
  >>> y.__class__.__name__
  'Y'
  >>> y.context is x
  True

ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ::

  >>> class Y2(Y):
  ...     pass

  >>> registry.register([IR], IP1, 'bob', Y2)
  >>> y = registry.queryAdapter(x, IP1, 'bob')
  >>> y.__class__.__name__
  'Y2'
  >>> y.context is x
  True

Когда Ρ„Π°Π±Ρ€ΠΈΠΊΠ° для Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ `None` - это рассматриваСтся ΠΊΠ°ΠΊ Ссли Π±Ρ‹
Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ Π½Π΅ Π±Ρ‹Π» Π½Π°ΠΉΠ΄Π΅Π½. Π­Ρ‚ΠΎ позволяСт Π½Π°ΠΌ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π°Ρ†ΠΈΠΈ (ΠΏΠΎ ТСланию) ΠΈ Π΄Π°Π΅Ρ‚
Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ„Π°Π±Ρ€ΠΈΠΊΠ΅ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° Π»ΠΈ адаптация ΠΎΡΠ½ΠΎΠ²Ρ‹Π²Π°ΡΡΡŒ Π½Π°
состоянии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ адаптируСтся::

  >>> def factory(context):
  ...     if context.name == 'object':
  ...         return 'adapter'
  ...     return None

  >>> class Object(object):
  ...     zope.interface.implements(IR)
  ...     name = 'object'

  >>> registry.register([IR], IP1, 'conditional', factory) 
  >>> obj = Object()
  >>> registry.queryAdapter(obj, IP1, 'conditional')
  'adapter'
  >>> obj.name = 'no object'
  >>> registry.queryAdapter(obj, IP1, 'conditional') is None
  True
  >>> registry.queryAdapter(obj, IP1, 'conditional', 'default')
  'default'

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для прСдоставлСния Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΊΠ°ΠΊ ΠΈ
`queryAdapter()` - это `adapter_hook()`::

  >>> y = registry.adapter_hook(IP1, x)
  >>> y.__class__.__name__
  'Y'
  >>> y.context is x
  True
  >>> y = registry.adapter_hook(IP1, x, 'bob')
  >>> y.__class__.__name__
  'Y2'
  >>> y.context is x
  True

`adapter_hook()` просто мСняСт порядок Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ интСрфСйса. Π­Ρ‚ΠΎ
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для встраивания Π² ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² интСрфСйсов.

АдаптСры ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
---------------------

Иногда Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Ρ…ΠΎΡ‚Π΅Ρ‚ΡŒ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ
Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ. Для этого Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ None ΠΊΠ°ΠΊ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ интСрфСйс::

  >>> registry.register([None], IP1, '', 1)

послС этого Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ для интСрфСйсов для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρƒ
вас Π½Π΅Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°::

  >>> class IQ(zope.interface.Interface):
  ...     pass
  >>> registry.lookup([IQ], IP1, '')
  1

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ всС Π΅Ρ‰Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ::

  >>> registry.lookup([IR2], IP1, '')
  21

АдаптСры классов
----------------

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ классов, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π°
Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΠΈΡ… для классов::

  >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', 'C21')
  >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
  'C21'

АдаптСры для словарСй
---------------------

Π’ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π±Ρ‹Π»ΠΎ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹ основанныС Π½Π°
словарях ΠΈΠ·-Π·Π° ошибки. Π”Π°Π²Π°ΠΉΡ‚Π΅ удостовСримся Ρ‡Ρ‚ΠΎ это Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚::

  >>> adapter = {}
  >>> registry.register((), IQ, '', adapter)
  >>> registry.lookup((), IQ, '') is adapter
  True

Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ рСгистрации
--------------------

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ рСгистрируя None вмСсто ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°::

  >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', None)
  >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
  21

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ это Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ None Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ зарСгистрирован. Π­Ρ‚ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ
ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΡŽ Π²Ρ‹ΡˆΠ΅ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ рССстр Π½Π΅ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ рСгистрируСтся.

ΠœΡƒΠ»ΡŒΡ‚ΠΈ-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹
===============

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ нСсколько спСцификаций::

  >>> registry.register([IR1, IQ], IP2, '', '1q2')
  >>> registry.lookup([IR1, IQ], IP2, '')
  '1q2'
  >>> registry.lookup([IR2, IQ], IP1, '')
  '1q2'

  >>> class IS(zope.interface.Interface):
  ...     pass
  >>> registry.lookup([IR2, IS], IP1, '')

  >>> class IQ2(IQ):
  ...     pass

  >>> registry.lookup([IR2, IQ2], IP1, '')
  '1q2'

  >>> registry.register([IR1, IQ2], IP2, '', '1q22')
  >>> registry.lookup([IR2, IQ2], IP1, '')
  '1q22'

ΠœΡƒΠ»ΡŒΡ‚ΠΈ-адаптация
----------------

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ нСсколько ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²::

  >>> class Q:
  ...     zope.interface.implements(IQ)

Как ΠΈ с ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΌΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°ΠΌΠΈ, ΠΌΡ‹ рСгистрируСм Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
класс::

  >>> class IM(zope.interface.Interface):
  ...     pass
  >>> class M:
  ...     zope.interface.implements(IM)
  ...     def __init__(self, x, q):
  ...         self.x, self.q = x, q
  >>> registry.register([IR, IQ], IM, '', M)

И Π·Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ `queryMultiAdapter` для вычислСния Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°::

  >>> q = Q()
  >>> m = registry.queryMultiAdapter((x, q), IM)
  >>> m.__class__.__name__
  'M'
  >>> m.x is x and m.q is q
  True

ΠΈ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π°::

  >>> class M2(M):
  ...     pass
  >>> registry.register([IR, IQ], IM, 'bob', M2)
  >>> m = registry.queryMultiAdapter((x, q), IM, 'bob')
  >>> m.__class__.__name__
  'M2'
  >>> m.x is x and m.q is q
  True

АдаптСры ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
---------------------

Как ΠΈ для ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Ρ… Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²
None вмСсто *ΠΏΠ΅Ρ€Π²ΠΎΠΉ* спСцификации::

  >>> registry.register([None, IQ], IP2, '', 'q2')
  >>> registry.lookup([IS, IQ], IP2, '')
  'q2'

НулСвыС Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹
================

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±Π΅Π· спСцификации::

  >>> registry.register([], IP2, '', 2)
  >>> registry.lookup([], IP2, '')
  2
  >>> registry.lookup([], IP1, '')
  2

ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ²
----------------------------------

АдаптСры ΠΈΠΌΠ΅ΡŽΡ‚ ΠΈΠΌΠ΅Π½Π°. Иногда это ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для получСния всСх ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ…
Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² для Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ интСрфСйса::

  >>> adapters = list(registry.lookupAll([IR1], IP1))
  >>> adapters.sort()
  >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]

Π­Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈ для ΠΌΡƒΠ»ΡŒΡ‚ΠΈ-Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ²::

  >>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
  >>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
  >>> adapters.sort()
  >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]

И Π΄Π°ΠΆΠ΅ для Π½ΡƒΠ»Π΅Π²Ρ‹Ρ… Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ²::

  >>> registry.register([], IP2, 'bob', 3)
  >>> adapters = list(registry.lookupAll([], IP1))
  >>> adapters.sort()
  >>> assert adapters == [(u'', 2), (u'bob', 3)]

Подписки
========

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π±Π»ΠΈΠ·ΠΊΠΎ соотвСтствуСт
спСцификации. Иногда ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚
ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ спСцификации. ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ подписки для этого. ΠœΡ‹ подписываСм
ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ для спСцификаций ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠ·ΠΆΠ΅ Π½Π°Ρ…ΠΎΠ΄ΠΈΠΌ всС подписанныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹::

  >>> registry.subscribe([IR1], IP2, 'sub12 1')
  >>> registry.subscriptions([IR1], IP2)
  ['sub12 1']

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² подписки Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΈΠΌΠ΅Π½.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ нСсколько подписчиков для ΠΎΠ΄Π½ΠΎΠΉ спСцификации::

  >>> registry.subscribe([IR1], IP2, 'sub12 2')
  >>> registry.subscriptions([IR1], IP2)
  ['sub12 1', 'sub12 2']

Если подписчики зарСгистрированы для ΠΎΠ΄Π½ΠΈΡ… ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Ρ… интСрфСйсов, ΠΎΠ½ΠΈ
Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ Π² порядкС опрСдСлСния.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ подписчики для всСх спСцификаций ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ None::

  >>> registry.subscribe([None], IP1, 'sub_1')
  >>> registry.subscriptions([IR2], IP1)
  ['sub_1', 'sub12 1', 'sub12 2']

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π½ΠΎΠ²Ρ‹ΠΉ подписчик возвращаСтся ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ. ΠŸΠΎΠ΄ΠΏΠΈΡΡ‡ΠΈΠΊΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅
для ΠΌΠ΅Π½Π΅Π΅ ΠΎΠ±Ρ‰ΠΈΡ… Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Ρ… интСрфСйсов Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅Π΄ подписчиками
для Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰ΠΈΡ… интСрфСйсов.

Подписки ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠ΅ΠΆΠ΄Ρƒ нСсколькими совмСстимыми спСцификациями::

  >>> registry.subscriptions([IR2], IP1)
  ['sub_1', 'sub12 1', 'sub12 2']
  >>> registry.subscribe([IR1], IP1, 'sub11')
  >>> registry.subscriptions([IR2], IP1)
  ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
  >>> registry.subscribe([IR2], IP2, 'sub22')
  >>> registry.subscriptions([IR2], IP1)
  ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
  >>> registry.subscriptions([IR2], IP2)
  ['sub12 1', 'sub12 2', 'sub22']

Подписки ΠΌΠΎΠ³ΡƒΡ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… спСцификаций::

  >>> registry.subscribe([IR1, IQ], IP2, 'sub1q2')
  >>> registry.subscriptions([IR1, IQ], IP2)
  ['sub1q2']

Как ΠΈ с ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΌΠΈ подписчиками ΠΈ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°ΠΌΠΈ Π±Π΅Π· подписок, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ
None для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ³ΠΎ интСрфСйса, Ρ‡Ρ‚ΠΎ Π±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ::

  >>> registry.subscribe([None, IQ], IP2, 'sub_q2')
  >>> registry.subscriptions([IS, IQ], IP2)
  ['sub_q2']
  >>> registry.subscriptions([IR1, IQ], IP2)
  ['sub_q2', 'sub1q2']

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ подписки ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ нСзависимы ΠΎΡ‚ Π»ΡŽΠ±Ρ‹Ρ… спСцификаций::

  >>> list(registry.subscriptions([], IP1))
  []

  >>> registry.subscribe([], IP2, 'sub2')
  >>> registry.subscriptions([], IP1)
  ['sub2']
  >>> registry.subscribe([], IP1, 'sub1')
  >>> registry.subscriptions([], IP1)
  ['sub2', 'sub1']
  >>> registry.subscriptions([], IP2)
  ['sub2']

Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ рСгистрации подписчиков
--------------------------------

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ подписчиков. ΠŸΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ рСгистрации подписчика
ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°::

  >>> registry.unsubscribe([IR1], IP1, 'sub11')
  >>> registry.subscriptions([IR1], IP1)
  ['sub_1', 'sub12 1', 'sub12 2']

Если ΠΌΡ‹ Π½Π΅ Π·Π°Π΄Π°Π΅ΠΌ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ значСния Ρ‚ΠΎΠ³Π΄Π° подписки Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ для всСх
подписчиков ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰ΠΈΡ… с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ интСрфСйсом::

  >>> registry.unsubscribe([IR1], IP2)
  >>> registry.subscriptions([IR1], IP1)
  ['sub_1']

АдаптСры подписки
-----------------

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΡ‹ рСгистрируСм Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ для Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ
Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡ‚ΡŒ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Ρ‹, Π½ΠΎ с подписками ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ нСсколько Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ². Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€
подписчика для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²::

  >>> registry.subscribe([IR, IQ], IM, M)
  >>> registry.subscribe([IR, IQ], IM, M2)

  >>> subscribers = registry.subscribers((x, q), IM)
  >>> len(subscribers)
  2
  >>> class_names = [s.__class__.__name__ for s in subscribers]
  >>> class_names.sort()
  >>> class_names
  ['M', 'M2']
  >>> [(s.x is x and s.q is q) for s in subscribers]
  [True, True]

подписчики Ρ„Π°Π±Ρ€ΠΈΠΊ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ None::

  >>> def M3(x, y):
  ...     return None

  >>> registry.subscribe([IR, IQ], IM, M3)
  >>> subscribers = registry.subscribers((x, q), IM)
  >>> len(subscribers)
  2

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ
-----------

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ - это подписанная Ρ„Π°Π±Ρ€ΠΈΠΊΠ° которая Π½Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ
значСния. Она Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ None. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ отличаСтся ΠΎΡ‚ Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΎΠ² Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½
Π΄Π΅Π»Π°Π΅Ρ‚ всю Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΊΠΎΠ³Π΄Π° вызываСтся Ρ„Π°Π±Ρ€ΠΈΠΊΠ°.

Для рСгистрации ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Π½Π°Π΄ΠΎ просто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ None ΠΊΠ°ΠΊ прСдоставляСмый
интСрфСйс::

  >>> def handler(event):
  ...     print 'handler', event

  >>> registry.subscribe([IR1], None, handler)
  >>> registry.subscriptions([IR1], None) == [handler]
  True

Hry