如何获得"演员喜欢"适应纯zope.interface?

时间:2014-07-16 21:38:34

标签: python zope.interface zope.component

我想得到" C ++演员喜欢"适应使用zope.interface的代码。在我的实际用例中,我使用了来自Pyramid的注册表,但它派生自zope.interface.registry.Components,根据changes.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>,   < InterfaceClass .... IB>)

知道如何让这个工作吗?

1 个答案:

答案 0 :(得分:2)

要使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自述文件中的Adaptation

您可以使用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'>