我想得到" 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>)
知道如何让这个工作吗?
答案 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'>