Как получить адаптацию "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'>
Другие вопросы по тегам