[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