Commit 3739f777 authored by Hanno Schlichting's avatar Hanno Schlichting

Updated the what's new in AQ section with philiKON's feedback

parent ab3d353d
...@@ -134,26 +134,31 @@ All classes, which wanted to interact with Zope2 in any non-trivial way, had to ...@@ -134,26 +134,31 @@ All classes, which wanted to interact with Zope2 in any non-trivial way, had to
inherit from the Acquisition base classes. As a result almost no external inherit from the Acquisition base classes. As a result almost no external
package could directly work inside Zope2 but required an integration layer. package could directly work inside Zope2 but required an integration layer.
With this version of Zope2 classes do have a second option of providing With this version of Zope2, objects have a new option of providing location
location awareness to Zope API's in a transparent way. The second option is the awareness to Zope APIs. This new option is to provide an explicit parent
`zope.location <http://pypi.python.org/pypi/zope.location>`_ API as described pointer in the ``__parent__`` attribute, much like specified by the ILocation
by the ILocation interface. API from `zope.location <http://pypi.python.org/pypi/zope.location>`_. Browser
views and other location-dependent components implement ILocation already.
Classes implementing this interface get `__parent__` pointers set to their
container object, when being put into the container. Code that operates on such Classes adhering to this convention need to get `__parent__` pointers set to
objects can then walk up the containment hierarchy by following the pointers. their container object, when being put into the container. Code that operates
In Acquisition based classes no information would be stored on the objects, but on such objects can then walk up the containment hierarchy by following the
Acquisition wrappers are constructed around the objects instead. Only those pointers. In Acquisition based classes no information would be stored on the
wrappers would hold the container references. The Acquisition wrapping relies objects, but Acquisition wrappers are constructed around the objects instead.
on the objects to provide an `__of__` method as done by the Acquisition base Only those wrappers would hold the container references. The Acquisition
classes. wrapping relies on the objects to provide an `__of__` method as done by the
Acquisition base classes.
The standard way of getting the container of an instance is to call::
The most common way of getting the container of an instance is to call::
from Acquisition import aq_parent from Acquisition import aq_parent
container = aq_parent(instance) container = aq_parent(instance)
For instances providing the ILocation interface the common way is::
container = instance.__parent__
There are various `aq_*` methods available for various other tasks related to There are various `aq_*` methods available for various other tasks related to
locating objects in the containment hierarchy. So far virtually all objects in locating objects in the containment hierarchy. So far virtually all objects in
Zope2 would participate in Acquisition. As a side-effect many people relied on Zope2 would participate in Acquisition. As a side-effect many people relied on
...@@ -174,53 +179,58 @@ it with a proper interface check:: ...@@ -174,53 +179,58 @@ it with a proper interface check::
In addition to this check you should no longer rely on the `aq_*` methods to be In addition to this check you should no longer rely on the `aq_*` methods to be
available as attributes. While all code inside Zope2 itself still supports available as attributes. While all code inside Zope2 itself still supports
this, it does no longer rely on thosem but makes proper use of the functions this, it does no longer rely on those but makes proper use of the functions
provided by the Acquisition package. provided by the Acquisition package.
To understand the interaction between the new and old approach here is a To understand the interaction between the new and old approach here is a
little example:: little example::
>>> class O(object): >>> class Location(object):
... def __init__(self, name): ... def __init__(self, name):
... self.__name__ = str(name) ... self.__name__ = name
... def __repr__(self): ... def __repr__(self):
... return self.__class__.__name__ + self.__name__ ... return self.__name__
# Create an Acquisition variant of the class: # Create an Acquisition variant of the class:
>>> from Acquisition import Implicit >>> import Acquisition
>>> class I(O, Implicit): >>> class Implicit(Location, Acquisition.Implicit):
... pass ... pass
>>> i1 = I(1) # Create two implicit instances:
>>> i2 = I(2)
>>> o1 = O(1) >>> root = Implicit('root')
>>> o2 = O(2) >>> folder = Implicit('folder')
# And two new Acquisition-free instances:
>>> container = Location('container')
>>> item = Location('item')
# Provide the containment hints: # Provide the containment hints:
>>> i2 = i2.__of__(i1) >>> folder = folder.__of__(root)
>>> o1.__parent__ = i2 >>> container.__parent__ = folder
>>> o2.__parent__ = o1 >>> item.__parent__ = container
# Test the containtment chain: # Test the containtment chain:
>>> from Acquisition import aq_parent >>> from Acquisition import aq_parent
>>> aq_parent(o1) >>> aq_parent(container)
I2 folder
>>> from Acquisition import aq_chain >>> from Acquisition import aq_chain
>>> aq_chain(o2) >>> aq_chain(item)
[O2, O1, I2, I1] [item, container, folder, root]
# Explicit pointers take precedence over Acquisition wrappers: # Explicit pointers take precedence over Acquisition wrappers:
>>> i3 = I(3) >>> item2 = Implicit('item2')
>>> i3 = i3.__of__(i2) >>> item2 = item2.__of__(folder)
>>> i3.__parent__ = o1 >>> item2.__parent__ = container
>>> aq_chain(i3) >>> aq_chain(item2)
[I3, O1, I2, I1] [item2, container, folder, root]
For a less abstract example, you so far had to do:: For a less abstract example, you so far had to do::
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment