Как получить адаптацию "cast like" для работы с чистым zope.interface?
Я хотел бы получить адаптацию "C++ cast like" для работы с кодом из zope.interface
, В моем реальном случае я использую реестр от Pyramid
но это вытекает из zope.interface.registry.Components
который в соответствии с изменениями.txt был введен, чтобы иметь возможность использовать этот материал без какой-либо зависимости от zope.components
, И следующий пример завершен и самодостаточен:
from zope.interface import Interface, implements
from zope.interface.registry import Components
registry = Components()
class IA(Interface):
pass
class IB(Interface):
pass
class A(object):
implements(IA)
class B(object):
implements(IB)
def __init__(self,other):
pass
registry.registerAdapter(
factory=B,
required=[IA]
)
a = A()
b = registry.getAdapter(a,IB) # why instance of B and not B?
b = IB(A()) # how to make it work?
интересно, почему registry.getAdapter
уже возвращает адаптированный объект, который является экземпляром B
в моем случае. Я бы ожидал, чтобы вернуться в класс B
, но, возможно, мое понимание термина адаптер неверно. Поскольку эта строка работает и, очевидно, корректирующий код зарегистрирован правильно, я также ожидаю, что последняя строка будет работать. Но это терпит неудачу с ошибкой как это:
TypeError: ("Не удалось адаптировать", <.... Объект в 0x4d1c3d0>,
)
Есть идеи, как заставить это работать?
1 ответ
Делать IB(A())
работать, вам нужно добавить крюк к zope.interface.adapter_hooks
список; IAdapterRegistry
интерфейс имеет выделенный IAdapterRegistry.adapter_hook
метод, который мы можем использовать для этого:
from zope.interface.interface import adapter_hooks
adapter_hooks.append(registry.adapters.adapter_hook)
См. Адаптация в zope.interface
ПРОЧТИ МЕНЯ.
Вы можете использовать IAdapterRegistry.lookup1()
метод для поиска с одним адаптером без вызова фабрики:
from zope.interface import providedBy
adapter_factory = registry.adapters.lookup1(providedBy(a), IB)
Опираясь на ваш образец:
>>> from zope.interface.interface import adapter_hooks
>>> adapter_hooks.append(registry.adapters.adapter_hook)
>>> a = A()
>>> IB(a)
<__main__.B object at 0x100721110>
>>> from zope.interface import providedBy
>>> registry.adapters.lookup1(providedBy(a), IB)
<class '__main__.B'>