[Zope-CMF] __setattr__ in a persistent class
Chris Withers
chrisw@nipltd.com
Thu, 31 Jul 2003 15:05:25 +0100
Gregoire Weber wrote:
> Hi all!
>
> Q: Somebody on the list, knowing how to intercept attribute
> setting and getting with __setattr__ and __getattr__ in
> a persistent subclass?
A: Don't do this, explain what your problem is and fidn a better solution :-)
> What I like to do:
>
> I created a CMF content type named TransBag (a (semi)
> transparent bag holding another content object) that
> should hold other content object.
>
> This should allow selective access (read and write) to
> attributes of the content object (like title, description,
> etc) and to the bag (like portal_type, workflow_history).
>
> This selective access should be totally transparent for
> existing CMF tools like portal_metadata etc.
>
> I need this concept for the next versions of CMFCollection.
Can you explain why? Not sure what CMFCollection does and don't quite grok the
stuff above...
> I've stepped through the code with the pdb and recognized
> that setting self._p_changed = 1 doesn't help. It seems
> that self._p_changed is some kind of write protected.
> Resulting in 0 (zero) after the write!
don't trust that. self._p_changed=1 definitely works, but is likely highyl 'magic'.
see inserts below...
> def __setattr__(self, name, value):
> """Intercept attribute setting.
> """
> if self._isDirectAccessAllowed(name): # '_blah' etc.
> # set attribute to TransBag object
> self.__dict__[name] = value
self._p_changed = 1
> else:
> # set attribute to '_attrs' dictionary to be able
> # to intercept attribute reading with '__getattr__'
> self.__dict__['_attrs'][name] = value
> self._p_changed = 1
self.__dict__['_attrs']._p_changed = 1
> def __getattr__(self, name):
> """Intercept attribute getting.
>
> Called if attribute does not exist on the object
> (because intercepted in __setattr__ or aquired)
> """
> if name in self._attrs.keys():
> return self._attrs[name]
>
> # without this aquisition would not work
> raise AttributeError
raise AttributeError,name
Hmmm... that said, I don't really understand what you're trying to do, so the
above suggestions may be bogus...
Chris