[ZODB-Dev] Computed Attributes and property's

Tim Peters tim at zope.com
Tue May 17 16:59:41 EDT 2005


[Stephen Masterman]
> Does ZODB have something equivalent to Durus' Computed Attributes? Which
> I understand are attributes (or methods) on a Persistent object that
> compute a value from some other attributes and then cache that result for
> each connection, and if any of the attributes from which the Computed
> Attribute computes its result change, the new result will be
> automatically computed and all connections will have their cached value
> invalidated.

I don't know.  My understanding is that ComputedAttribute (one word) is a
subclass of Persistent in Durus.  I haven't used it, and I don't understand
the explanations I found online.

> On a related note, do properties work with Persistent objects in ZODB? I
> mean the Python property() function. I do not know how it interacts with
> __getattr__() and stuff, and I know the ZODB docs warn against messing
> with those functions for Persistent classes.

Which ZODB docs do you have in mind?  I'm not disputing them <wink>, I just
have no idea what you've been reading, since I don't think the ZODB/ZEO
Programming Guide mentions this, and that's about the only semi-official
ZODB user documentation that exists:

    http://www.zope.org/Wikis/ZODB/FrontPage/guide

> If they do work, do they basically serve as a non-cached computed
> attribute?

In general, I don't expect most "newer" Python class features (like
properties) to work in any ZODB before 3.3.  Persistent was an
ExtensionClass then, which is a dark maze of C code designed long before the
newer Python class features.  OTOH, I expect newer class features to work in
ZODB >= 3.3, where Persistent is a "vanilla" new-style Python class.

What a property "serves as" depends 100% on the code you write to implement
one.  Python's property mechanism just gives you a way to intercept attempts
to set, get, or delete an attribute -- what you do then is entirely up to
you.  Here's an example (which I just wrote & run under ZODB 3.4) where the
property "product" acts like a cached, computed, read-only attribute:

"""
import ZODB
import transaction
from persistent import Persistent

class MagicalProduct(Persistent):
    _v_cached = None # instance sees this if it doesn't have its own

    def __init__(self, a, b):
        self.a, self.b = a, b

    def __product(self):
        if self._v_cached is not None:
            print "gotten from cache"
            return self._v_cached
        print "computed fresh"
        result = self._v_cached = self.a * self.b
        return result

    product = property(__product)

from ZODB.FileStorage import FileStorage
st = FileStorage("product.fs")
db = ZODB.DB(st)

cn = db.open()
p1 = MagicalProduct(3, 5)
print p1.product # computed fresh; 15
print p1.product # gotten from cache; 15

cn.root()['p1'] = p1
transaction.commit()

cn2 = db.open()
p2 = cn2.root()['p1']
print p2.product # computed fresh; 15
print p2.product # gotten from cache; 15

p1.a = 12
transaction.commit()
print p1.product # NOTE WELL:  gotten from cache; 15
print p2.product # computed fresh; 60
"""

There's lots going on in the last two lines.  First, _v_ attributes (like
_v_cached above) are special to ZODB, and get destroyed "by magic" when an
object is unloaded:

    http://www.zope.org/Wikis/ZODB/VolatileAttributes

We got 15 in the penultimate line because a connection does not send
invalidation messages to itself; it thinks it already has up-to-date state.

That cn2 saw the invalidation "by magic" relies on a new ZODB 3.4 feature
(in current SVN 3.4 branch; not yet in a released tarball/installer):  a
transaction object now calls registered afterCompletion() methods after a
transaction commits or aborts, and Connections register with transactions in
3.3+, and their afterCompletion() methods process invalidations in 3.4+.  In
3.3, you would need to do (e.g.) an explicit cn2.sync() for the last line to
print 60 instead of 15.

> Is a Durus Computed Attribute just a property with caching and
> consistency for multiple connections? (I know this isn't a Durus list.)

Sorry, don't know.

> I'm developing an application for my job that uses ZODB. I think ZODB is
> awesome and it has been very instructive studying the code and
> documentation and the archives for this list. So thanks all you people
> who write this great software and help others understand it.

You're welcome!

> I eventually hope to produce something useful for less experienced
> programmers (like me) about indexing strategies and techniques. Indexing
> turns out to be somewhat complicated with important tradeoffs to
> consider.

If you're still thinking just "somewhat", your ambitions still have plenty
of room to grow <wink>.



More information about the ZODB-Dev mailing list