Given the following code:
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
The output it produces is:
<__main__.AB object at 0xb242290>
<__main__.AC object at 0xb2422d0>
Why is an instance of AB returned? AB only declares that it adapts A and B. Is there a way I can achieve behavior where only AC would be returned?
You are listing subscribers. Subscribers are notified of all things that implement the interface(s) they are interested in.
C
is a subclass ofB
, so theB
subscriber is interested, and will be notified. The fact thatC
implements a little more is of no concern to theB
subscriber, as the object will implement at least theB
interface.Subscribers are generic, they just want objects that implement their interface or subclasses thereof. Adapters are more specific:
getAdapters()
enumerates all registered adapters, together with their names: