2

我想获得“C++ cast like”改编以使用来自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: ('Could not adapt', <....A object at 0x4d1c3d0>, < InterfaceClass ....IB>)

知道如何让它工作吗?

4

1 回答 1

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

您可以使用该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'>
于 2014-07-16T21:58:17.643 回答