【问题标题】:How to get "cast like" adaption to work with pure zope.interface?如何让“cast like”适应纯 zope.interface?
【发布时间】:2014-07-16 21:38:34
【问题描述】:

我想获得“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>, )

知道如何让它工作吗?

【问题讨论】:

    标签: python zope.interface zope.component


    【解决方案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 自述文件中的 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'>
    

    【讨论】:

      猜你喜欢
      • 2012-05-26
      • 2015-05-24
      • 2019-10-08
      • 2014-02-11
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 2014-03-02
      • 2015-10-23
      相关资源
      最近更新 更多