给出以下代码:
from zope.component import getGlobalSiteManager, adapts, subscribers
from zope.interface import Interface, implements
class A(object): pass
class B(object): pass
class C(B): pass
class AB(object):
implements(Interface)
adapts(A, B)
def __init__(self, a, b):
pass
class AC(object):
implements(Interface)
adapts(A, C)
def __init__(self, a, c):
pass
gsm = getGlobalSiteManager()
gsm.registerSubscriptionAdapter(AB)
gsm.registerSubscriptionAdapter(AC)
a = A()
c = C()
for adapter in subscribers([a, c], Interface):
print adapter
它产生的输出是:
<__main__.AB object at 0xb242290>
<__main__.AC object at 0xb2422d0>
为什么返回AB的实例? AB只声明它适应A和B.有没有办法可以实现只返回AC的行为?
答案 0 :(得分:2)
您正在列出订阅者。订阅者会收到实现他们感兴趣的界面的所有内容的通知。
C
是B
的子类,因此B
订阅者感兴趣,并会收到通知。 C
实现更多一点的事实与B
订阅者无关,因为该对象将实现至少 B
接口。
订阅者是通用的,他们只是想要实现其接口或其子类的对象。适配器更具体:
>>> gsm.registerAdapter(AB)
>>> gsm.registerAdapter(AC)
>>> from zope.component import getAdapters
>>> for adapter in getAdapters((a, c), Interface):
... print adapter
...
(u'', <__main__.AC object at 0x104b25a90>)
getAdapters()
枚举所有已注册的适配器及其名称:
>>> class AnotherAC(object):
... implements(Interface)
... adapts(A, C)
... def __init__(self, a, c): pass
...
>>> gsm.registerAdapter(AnotherAC, name=u'another')
>>> for adapter in getAdapters((a, c), Interface):
... print adapter
...
(u'', <__main__.AC object at 0x104b25ed0>)
(u'another', <__main__.AnotherAC object at 0x104b25a90>)