当前位置: 动力学知识库 > 问答 > 编程问答 >

python - How to get "cast like" adaption to work with pure zope.interface?

问题描述:

I would like to get the "C++ cast like" adaption to work with the code from zope.interface. In my real use case, I'm using a registry from Pyramid but it derives from zope.interface.registry.Components, which according to the changes.txt was introduced to be able to use this stuff without any dependency on zope.components. And the following example is complete and self contained:

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?

I wonder why registry.getAdapter already returns the adapted object, which is an instance of B in my case. I would have expected to get back the class B, but perhaps my understanding of the term adapter is wrong. As this line works and obviously the adapting code is registered correctly, I would also expect the last line to work. But it fails with an error like this:

TypeError: ('Could not adapt', <....A object at 0x4d1c3d0>,

< InterfaceClass ....IB>)

Any idea how to get this working?

网友答案:

To make IB(A()) work, you need to add a hook to the the zope.interface.adapter_hooks list; the IAdapterRegistry interface has a dedicated IAdapterRegistry.adapter_hook method we can use for this:

from zope.interface.interface import adapter_hooks

adapter_hooks.append(registry.adapters.adapter_hook)

See Adaptation in the zope.interface README.

You can use the IAdapterRegistry.lookup1() method to do single-adapter lookups without invoking the factory:

from zope.interface import providedBy

adapter_factory = registry.adapters.lookup1(providedBy(a), IB)

Building on your sample:

>>> 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'>
分享给朋友:
您可能感兴趣的文章:
随机阅读: