Adapter Registration APIs¶
Conforming Adapter Lookup¶
The getAdapterInContext()
and
queryAdapterInContext()
APIs first check the
context object to see if it already conforms to the requested interface.
If so, the object is returned immediately. Otherwise, the adapter factory
is looked up in the site manager, and called.
Let’s start by creating a component that supports the __conform__() method:
We also gave the component a custom representation, so it will be easier to use in these tests.
We now have to create a site manager (other than the default global one) with which we can register adapters for I1.
Now we create a new context that knows how to get to our custom site manager.
If an object implements the interface you want to adapt to, getAdapterInContext() should simply return the object.
If an object conforms to the interface you want to adapt to, getAdapterInContext() should simply return the conformed object.
If an adapter isn’t registered for the given object and interface, and you provide no default, the getAdapterInContext API raises ComponentLookupError:
While the queryAdapterInContext API returns the default:
If you ask for an adapter for which something’s registered you get the registered adapter:
Named Adapter Lookup¶
The getAdapter
and queryAdapter
API functions are similar to
{get|query}AdapterInContext()
functions, except that they do not care
about the __conform__()
but also handle named adapters. (Actually, the
name is a required argument.)
If no adapter is registered for the given object, interface, and name,
getAdapter
raises ComponentLookupError
, while queryAdapter
returns the default:
The ‘requires’ argument to registerAdapter must be a sequence, rather than a single interface:
After register an adapter from I1 to I2 with the global site manager:
We can access the adapter using the getAdapter() API:
If we search using a non-anonymous name, before registering:
After registering under that name:
Invoking an Interface to Perform Adapter Lookup¶
zope.component
registers an adapter hook with
zope.interface.interface
, allowing a convenient spelling for
adapter lookup: just “call” the interface, passing the context:
If the lookup fails, we get a TypeError:
unless we pass a default:
Registering Adapters For Arbitrary Objects¶
Providing an adapter for None says that your adapter can adapt anything to I2.
It can really adapt any arbitrary object:
Looking Up Adapters Using Multiple Objects¶
Multi-adapters adapt one or more objects to another interface. To make this demonstration non-trivial, we need to create a second object to be adapted:
As with regular adapters, if an adapter isn’t registered for the given
objects and interface, the getMultiAdapter()
API
raises ComponentLookupError:
while the queryMultiAdapter()
API returns the default:
Note that name
is not a required attribute here.
To test multi-adapters, we also have to create an adapter class that handles to context objects:
Now we can register the multi-adapter:
Notice how the required interfaces are simply provided by a tuple.
Now we can get the adapter:
Finding More Than One Adapter¶
It is sometimes desireable to get a list of all adapters that are registered for a particular output interface, given a set of objects.
Let’s register some adapters first:
Now we get all the adapters that are registered for ob
that provide
I5
:
Note that the output doesn’t include None values. If an adapter factory returns None, it is as if it wasn’t present.