Oh! And reference to related Persistence modules (persistent mappings,
lists, BTrees):


On 2/14/06, Jeff Shell <[EMAIL PROTECTED]> wrote:
> On 2/14/06, Peter Bengtsson <[EMAIL PROTECTED]> wrote:
> > D'oh! That's confusing. Isn't there a class that gathers all of these in 
> > one.
> >
> > It seems confusing, you derive from Persistent but only some are accepted.
> > Does that mean that there's PersistentFloat and PersistentTuple too?
> > If not, why *only* dicts?
> As mentioned above, it applies to *mutable* objects.
> """
> Objects whose value can change are said to be mutable; objects whose
> value is unchangeable once they are created are called immutable. (The
> value of an immutable container object that contains a reference to a
> mutable object can change when the latter's value is changed; however
> the container is still considered immutable, because the collection of
> objects it contains cannot be changed. So, immutability is not
> strictly the same as having an unchangeable value, it is more subtle.)
> An object's mutability is determined by its type; for instance,
> numbers, strings and tuples are immutable, while dictionaries and
> lists are mutable.
> """
> http://docs.python.org/ref/objects.html
> Instances of Persistent based classes know when they change. Like if you do::
>     clive.age = 28
> Which is effectively ``setattr(clive, 'age', 28)``. As a persistent
> object, clive notices that an attribute is being set (even if it's
> replacing an existing value), and flags that 'clive' has changes that
> need to be saved. So again - here, it's the 'clive' object that's
> being updated in this case. The fact that the value is an integer
> doesn't matter. It's not changing. 28 is 28. But 'clive' is changing
> by having a new/updated 'age' attribute set.
> On the other hand, if you do::
>     clive.favoriteNumbers.append(13)
> 'clive' does not change. 'favoriteNumbers' changes. If favoriteNumbers
> is a regular Python list, the persistence machinery has no idea that
> it's changed. It's not being assigned to 'clive', it's already an
> attribute there and is not being replaced. So if it's not a
> PersistentList, it gets forgotten.
> If favoriteNumbers was a tuple, you couldn't append to it. You could
> do an addition, but in a form like this::
>     clive.favoriteNumbers = clive.favoriteNumbers + (13,)
>     # Alternately
>     clive.favoriteNumbers += (13,)
> This is doing assignment. 'clive' is getting a new attribute set, and
> as a Persistent object 'clive' can be set as needing its changes
> saved.
> It's not only dicts, it's dicts and lists (PersistentDict and PersistentList).
> I don't know if there's a PersistentSet. Python offers two sets since
> 2.3 - a mutable (list-like) one and an immutable (tuple-like) one. I
> imagine that if you use the mutable set (``sets.Set`` in 2.3, ``set``
> in 2.4), you'd run into the same problems. But if you used the
> immutable set (``sets.ImmutableSet``, ``frozenset`` in 2.4) you
> wouldn't.
> Note that this issue affects not just ZODB persistence. If you used
> even the simple 'shelve' module that's in Python, you have the same
> issue unless you use a 'writeback' option:
> """
> If the writeback parameter is True, the object will hold a cache of
> all entries accessed and write them back to the dict at sync and close
> times. This allows natural operations on mutable entries, but can
> consume much more memory and make sync and close take a long time.
> """
> So as a way of making working with default mutable objects feel
> natural, this option makes shelve read and write its whole database,
> which would obviously be very expensive for the ZODB.
> So - just use PersistentList and PersistentDict (or look into BTrees
> for better storage options).
> For more details, visit the ZODB documentation on ZODB programming,
> and visit the section on modifying mutable objects:
> http://www.zope.org/Wikis/ZODB/FrontPage/guide/node3.html

Jeff Shell
Zope3-users mailing list

Reply via email to