MINI MINI MANI MO
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Adapter Registration APIs — zope.configuration 4.0 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '4.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="zope.configuration 4.0 documentation" href="../index.html" />
<link rel="up" title="zope.component API Reference" href="../api.html" />
<link rel="next" title="Factory APIs" href="factory.html" />
<link rel="prev" title="Utility Registration APIs" href="utility.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="factory.html" title="Factory APIs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="utility.html" title="Utility Registration APIs"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">zope.configuration 4.0 documentation</a> »</li>
<li><a href="../api.html" accesskey="U"><tt class="docutils literal"><span class="pre">zope.component</span></tt> API Reference</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="adapter-registration-apis">
<h1>Adapter Registration APIs<a class="headerlink" href="#adapter-registration-apis" title="Permalink to this headline">¶</a></h1>
<div class="section" id="conforming-adapter-lookup">
<h2>Conforming Adapter Lookup<a class="headerlink" href="#conforming-adapter-lookup" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="xref py py-func docutils literal"><span class="pre">getAdapterInContext()</span></tt> and
<tt class="xref py py-func docutils literal"><span class="pre">queryAdapterInContext()</span></tt> 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.</p>
<p>Let’s start by creating a component that supports the <cite>__conform__()</cite> method:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.interface</span> <span class="kn">import</span> <span class="n">implementer</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">I1</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">I2</span>
<span class="gp">>>> </span><span class="nd">@implementer</span><span class="p">(</span><span class="n">I1</span><span class="p">)</span>
<span class="gp">... </span><span class="k">class</span> <span class="nc">Component</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">def</span> <span class="nf">__conform__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">iface</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">if</span> <span class="n">iface</span> <span class="o">==</span> <span class="n">I2</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">return</span> <span class="mi">42</span>
<span class="gp">>>> </span><span class="n">ob</span> <span class="o">=</span> <span class="n">Component</span><span class="p">()</span>
</pre></div>
</div>
<p>We also gave the component a custom representation, so it will be easier
to use in these tests.</p>
<p>We now have to create a site manager (other than the default global one)
with which we can register adapters for <cite>I1</cite>.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.globalregistry</span> <span class="kn">import</span> <span class="n">BaseGlobalComponents</span>
<span class="gp">>>> </span><span class="n">sitemanager</span> <span class="o">=</span> <span class="n">BaseGlobalComponents</span><span class="p">()</span>
</pre></div>
</div>
<p>Now we create a new <cite>context</cite> that knows how to get to our custom site
manager.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">ConformsToIComponentLookup</span>
<span class="gp">>>> </span><span class="n">context</span> <span class="o">=</span> <span class="n">ConformsToIComponentLookup</span><span class="p">(</span><span class="n">sitemanager</span><span class="p">)</span>
</pre></div>
</div>
<p>If an object implements the interface you want to adapt to,
<cite>getAdapterInContext()</cite> should simply return the object.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getAdapterInContext</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">queryAdapterInContext</span>
<span class="gp">>>> </span><span class="n">getAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I1</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">queryAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I1</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
</pre></div>
</div>
<p>If an object conforms to the interface you want to adapt to,
<cite>getAdapterInContext()</cite> should simply return the conformed object.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">getAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="go">42</span>
<span class="gp">>>> </span><span class="n">queryAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="go">42</span>
</pre></div>
</div>
<p>If an adapter isn’t registered for the given object and interface, and you
provide no default, the <cite>getAdapterInContext</cite> API raises ComponentLookupError:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.interface</span> <span class="kn">import</span> <span class="n">Interface</span>
<span class="gp">>>> </span><span class="k">class</span> <span class="nc">I4</span><span class="p">(</span><span class="n">Interface</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">pass</span>
<span class="gp">>>> </span><span class="n">getAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I4</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">ComponentLookupError</span>: <span class="n">(<Component implementing 'I1'>,</span>
<span class="go"> <InterfaceClass ...I4>)</span>
</pre></div>
</div>
<p>While the <cite>queryAdapterInContext</cite> API returns the default:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">queryAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I4</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="mi">44</span><span class="p">)</span>
<span class="go">44</span>
</pre></div>
</div>
<p>If you ask for an adapter for which something’s registered you get the
registered adapter:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">I3</span>
<span class="gp">>>> </span><span class="n">sitemanager</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="mi">43</span><span class="p">,</span> <span class="p">(</span><span class="n">I1</span><span class="p">,),</span> <span class="n">I3</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">getAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I3</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="go">43</span>
<span class="gp">>>> </span><span class="n">queryAdapterInContext</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I3</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="go">43</span>
</pre></div>
</div>
</div>
<div class="section" id="named-adapter-lookup">
<h2>Named Adapter Lookup<a class="headerlink" href="#named-adapter-lookup" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="docutils literal"><span class="pre">getAdapter</span></tt> and <tt class="docutils literal"><span class="pre">queryAdapter</span></tt> API functions are similar to
<tt class="docutils literal"><span class="pre">{get|query}AdapterInContext()</span></tt> functions, except that they do not care
about the <tt class="docutils literal"><span class="pre">__conform__()</span></tt> but also handle named adapters. (Actually, the
name is a required argument.)</p>
<p>If no adapter is registered for the given object, interface, and name,
<tt class="docutils literal"><span class="pre">getAdapter</span></tt> raises <tt class="docutils literal"><span class="pre">ComponentLookupError</span></tt>, while <tt class="docutils literal"><span class="pre">queryAdapter</span></tt>
returns the default:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getAdapter</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">queryAdapter</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">I2</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">ob</span>
<span class="gp">>>> </span><span class="n">getAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">ComponentLookupError</span>: <span class="n">(<instance Ob>,</span>
<span class="go"> <InterfaceClass zope.component.tests.examples.I2>,</span>
<span class="go"> '')</span>
<span class="gp">>>> </span><span class="n">queryAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">,</span> <span class="s">'<default>'</span><span class="p">)</span>
<span class="go">'<default>'</span>
</pre></div>
</div>
<p>The ‘requires’ argument to <cite>registerAdapter</cite> must be a sequence, rather than
a single interface:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getGlobalSiteManager</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">Comp</span>
<span class="gp">>>> </span><span class="n">gsm</span> <span class="o">=</span> <span class="n">getGlobalSiteManager</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="n">I1</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">the required argument should be a list of interfaces, not a single interface</span>
</pre></div>
</div>
<p>After register an adapter from <cite>I1</cite> to <cite>I2</cite> with the global site manager:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getGlobalSiteManager</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">Comp</span>
<span class="gp">>>> </span><span class="n">gsm</span> <span class="o">=</span> <span class="n">getGlobalSiteManager</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="p">(</span><span class="n">I1</span><span class="p">,),</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
</pre></div>
</div>
<p>We can access the adapter using the <cite>getAdapter()</cite> API:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">getAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">queryAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
</pre></div>
</div>
<p>If we search using a non-anonymous name, before registering:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">getAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">'named'</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">ComponentLookupError</span>: <span class="n">(<instance Ob>,</span>
<span class="go"> <InterfaceClass ....I2>,</span>
<span class="go"> 'named')</span>
<span class="gp">>>> </span><span class="n">queryAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">'named'</span><span class="p">,</span> <span class="s">'<default>'</span><span class="p">)</span>
<span class="go">'<default>'</span>
</pre></div>
</div>
<p>After registering under that name:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="p">(</span><span class="n">I1</span><span class="p">,),</span> <span class="n">I2</span><span class="p">,</span> <span class="s">'named'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">getAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">'named'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">queryAdapter</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">I2</span><span class="p">,</span> <span class="s">'named'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="invoking-an-interface-to-perform-adapter-lookup">
<h2>Invoking an Interface to Perform Adapter Lookup<a class="headerlink" href="#invoking-an-interface-to-perform-adapter-lookup" title="Permalink to this headline">¶</a></h2>
<p><tt class="xref py py-mod docutils literal"><span class="pre">zope.component</span></tt> registers an adapter hook with
<tt class="xref py py-mod docutils literal"><span class="pre">zope.interface.interface</span></tt>, allowing a convenient spelling for
adapter lookup: just “call” the interface, passing the context:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">I2</span><span class="p">(</span><span class="n">ob</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapted</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
</pre></div>
</div>
<p>If the lookup fails, we get a <cite>TypeError</cite>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">I2</span><span class="p">(</span><span class="nb">object</span><span class="p">())</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">('Could not adapt'...</span>
</pre></div>
</div>
<p>unless we pass a default:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">marker</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">adapted</span> <span class="o">=</span> <span class="n">I2</span><span class="p">(</span><span class="nb">object</span><span class="p">(),</span> <span class="n">marker</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapted</span> <span class="ow">is</span> <span class="n">marker</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="registering-adapters-for-arbitrary-objects">
<h2>Registering Adapters For Arbitrary Objects<a class="headerlink" href="#registering-adapters-for-arbitrary-objects" title="Permalink to this headline">¶</a></h2>
<p>Providing an adapter for None says that your adapter can adapt anything
to <cite>I2</cite>.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="p">(</span><span class="bp">None</span><span class="p">,),</span> <span class="n">I2</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapter</span> <span class="o">=</span> <span class="n">I2</span><span class="p">(</span><span class="n">ob</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
</pre></div>
</div>
<p>It can really adapt any arbitrary object:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">something</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">adapter</span> <span class="o">=</span> <span class="n">I2</span><span class="p">(</span><span class="n">something</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">Comp</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">context</span> <span class="ow">is</span> <span class="n">something</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="looking-up-adapters-using-multiple-objects">
<h2>Looking Up Adapters Using Multiple Objects<a class="headerlink" href="#looking-up-adapters-using-multiple-objects" title="Permalink to this headline">¶</a></h2>
<p>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:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component.tests.examples</span> <span class="kn">import</span> <span class="n">Ob2</span>
<span class="gp">>>> </span><span class="n">ob2</span> <span class="o">=</span> <span class="n">Ob2</span><span class="p">()</span>
</pre></div>
</div>
<p>As with regular adapters, if an adapter isn’t registered for the given
objects and interface, the <tt class="xref py py-func docutils literal"><span class="pre">getMultiAdapter()</span></tt> API
raises <cite>ComponentLookupError</cite>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getMultiAdapter</span>
<span class="gp">>>> </span><span class="n">getMultiAdapter</span><span class="p">((</span><span class="n">ob</span><span class="p">,</span> <span class="n">ob2</span><span class="p">),</span> <span class="n">I3</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">ComponentLookupError</span>:
<span class="go">((<instance Ob>, <instance Ob2>),</span>
<span class="go"> <InterfaceClass zope.component.tests.examples.I3>,</span>
<span class="go"> u'')</span>
</pre></div>
</div>
<p>while the <tt class="xref py py-func docutils literal"><span class="pre">queryMultiAdapter()</span></tt> API returns the default:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">queryMultiAdapter</span>
<span class="gp">>>> </span><span class="n">queryMultiAdapter</span><span class="p">((</span><span class="n">ob</span><span class="p">,</span> <span class="n">ob2</span><span class="p">),</span> <span class="n">I3</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'<default>'</span><span class="p">)</span>
<span class="go">'<default>'</span>
</pre></div>
</div>
<p>Note that <tt class="docutils literal"><span class="pre">name</span></tt> is not a required attribute here.</p>
<p>To test multi-adapters, we also have to create an adapter class that
handles to context objects:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.interface</span> <span class="kn">import</span> <span class="n">implementer</span>
<span class="gp">>>> </span><span class="nd">@implementer</span><span class="p">(</span><span class="n">I3</span><span class="p">)</span>
<span class="gp">... </span><span class="k">class</span> <span class="nc">DoubleAdapter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">first</span><span class="p">,</span> <span class="n">second</span><span class="p">):</span>
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">first</span> <span class="o">=</span> <span class="n">first</span>
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">second</span> <span class="o">=</span> <span class="n">second</span>
</pre></div>
</div>
<p>Now we can register the multi-adapter:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getGlobalSiteManager</span>
<span class="gp">>>> </span><span class="n">getGlobalSiteManager</span><span class="p">()</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">DoubleAdapter</span><span class="p">,</span> <span class="p">(</span><span class="n">I1</span><span class="p">,</span> <span class="n">I2</span><span class="p">),</span> <span class="n">I3</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
</pre></div>
</div>
<p>Notice how the required interfaces are simply provided by a tuple.</p>
<p>Now we can get the adapter:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">adapter</span> <span class="o">=</span> <span class="n">getMultiAdapter</span><span class="p">((</span><span class="n">ob</span><span class="p">,</span> <span class="n">ob2</span><span class="p">),</span> <span class="n">I3</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">DoubleAdapter</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">first</span> <span class="ow">is</span> <span class="n">ob</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="n">adapter</span><span class="o">.</span><span class="n">second</span> <span class="ow">is</span> <span class="n">ob2</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="finding-more-than-one-adapter">
<h2>Finding More Than One Adapter<a class="headerlink" href="#finding-more-than-one-adapter" title="Permalink to this headline">¶</a></h2>
<p>It is sometimes desireable to get a list of all adapters that are
registered for a particular output interface, given a set of
objects.</p>
<p>Let’s register some adapters first:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">I5</span><span class="p">(</span><span class="n">I1</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">pass</span>
<span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="p">[</span><span class="n">I1</span><span class="p">],</span> <span class="n">I5</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="n">Comp</span><span class="p">,</span> <span class="p">[</span><span class="bp">None</span><span class="p">],</span> <span class="n">I5</span><span class="p">,</span> <span class="s">'foo'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now we get all the adapters that are registered for <tt class="docutils literal"><span class="pre">ob</span></tt> that provide
<tt class="docutils literal"><span class="pre">I5</span></tt>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">zope.component</span> <span class="kn">import</span> <span class="n">getAdapters</span>
<span class="gp">>>> </span><span class="n">adapters</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">getAdapters</span><span class="p">((</span><span class="n">ob</span><span class="p">,),</span> <span class="n">I5</span><span class="p">))</span>
<span class="gp">>>> </span><span class="p">[(</span><span class="n">name</span><span class="p">,</span> <span class="n">adapter</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">adapter</span> <span class="ow">in</span> <span class="n">adapters</span><span class="p">]</span>
<span class="go">[(u'', 'Comp'), (u'foo', 'Comp')]</span>
</pre></div>
</div>
<p>Note that the output doesn’t include None values. If an adapter
factory returns None, it is as if it wasn’t present.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">gsm</span><span class="o">.</span><span class="n">registerAdapter</span><span class="p">(</span><span class="k">lambda</span> <span class="n">context</span><span class="p">:</span> <span class="bp">None</span><span class="p">,</span> <span class="p">[</span><span class="n">I1</span><span class="p">],</span> <span class="n">I5</span><span class="p">,</span> <span class="s">'nah'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">adapters</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">getAdapters</span><span class="p">((</span><span class="n">ob</span><span class="p">,),</span> <span class="n">I5</span><span class="p">))</span>
<span class="gp">>>> </span><span class="p">[(</span><span class="n">name</span><span class="p">,</span> <span class="n">adapter</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">adapter</span> <span class="ow">in</span> <span class="n">adapters</span><span class="p">]</span>
<span class="go">[(u'', 'Comp'), (u'foo', 'Comp')]</span>
</pre></div>
</div>
</div>
<div class="section" id="subscription-adapters">
<h2>Subscription Adapters<a class="headerlink" href="#subscription-adapters" title="Permalink to this headline">¶</a></h2>
</div>
<div class="section" id="event-handlers">
<h2>Event handlers<a class="headerlink" href="#event-handlers" title="Permalink to this headline">¶</a></h2>
</div>
<div class="section" id="helpers-for-declaring-testing-adapters">
<h2>Helpers for Declaring / Testing Adapters<a class="headerlink" href="#helpers-for-declaring-testing-adapters" title="Permalink to this headline">¶</a></h2>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Adapter Registration APIs</a><ul>
<li><a class="reference internal" href="#conforming-adapter-lookup">Conforming Adapter Lookup</a></li>
<li><a class="reference internal" href="#named-adapter-lookup">Named Adapter Lookup</a></li>
<li><a class="reference internal" href="#invoking-an-interface-to-perform-adapter-lookup">Invoking an Interface to Perform Adapter Lookup</a></li>
<li><a class="reference internal" href="#registering-adapters-for-arbitrary-objects">Registering Adapters For Arbitrary Objects</a></li>
<li><a class="reference internal" href="#looking-up-adapters-using-multiple-objects">Looking Up Adapters Using Multiple Objects</a></li>
<li><a class="reference internal" href="#finding-more-than-one-adapter">Finding More Than One Adapter</a></li>
<li><a class="reference internal" href="#subscription-adapters">Subscription Adapters</a></li>
<li><a class="reference internal" href="#event-handlers">Event handlers</a></li>
<li><a class="reference internal" href="#helpers-for-declaring-testing-adapters">Helpers for Declaring / Testing Adapters</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="utility.html"
title="previous chapter">Utility Registration APIs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="factory.html"
title="next chapter">Factory APIs</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/api/adapter.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="factory.html" title="Factory APIs"
>next</a> |</li>
<li class="right" >
<a href="utility.html" title="Utility Registration APIs"
>previous</a> |</li>
<li><a href="../index.html">zope.configuration 4.0 documentation</a> »</li>
<li><a href="../api.html" ><tt class="docutils literal"><span class="pre">zope.component</span></tt> API Reference</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2012, Zope Foundation Contributors.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>
OHA YOOOO