[Zope-dev] ObjectManagers and their children

Phillip J. Eby pje@telecommunity.com
Thu, 11 Nov 1999 18:47:11 -0500


At 09:34 PM 11/11/99 GMT, Ty Sarna wrote:
>In article <382B335F.3160393A@digicool.com>,
>Michel Pelletier  <michel@digicool.com> wrote:
>> 
>> I suspect jim would frown on another hook, we're trying to avoid as many
>> new hooks as possible, especialy ones that may have a per hit or per
>> traversal penalty.  Perhaps I haven't thought about your idea enough
>> though.
>
>Right. I'm just saying that if there does have to be a gross hack, I
>could accept that. It would be nice if it were simply possible to
>override __getattr__ in the usual manner. Or in an unusual manner, for
>that matter :-). So long as there's some way, I'm happy :-)
>

Actually, here's an unusual manner in which you can do what you want
(mostly).  :)

If you want a Persistent object that does __getattr__, all you need to do
is redefine its __of__ method thusly:

def __of__(self,context):
	me = Acquisiton.ImplicitAcquisitonWrapper(self,context) # normal self
	return Acquisiton.ImplicitAcquisitonWrapper(GetAttrWrapper(me),context)

and define GetAttrWrapper thusly:

class GetAttrWrapper(Acquisition.Implicit):
	def __init__(self,other):
		self._other = other

	def __getattr__(self,attr):

		other = self.__dict__['_other']

		try:	return other[attr]
		except KeyError:
			return getattr(other,attr)

	def __setattr__(self,attr,value):
		setattr(self.__dict__['_other'],attr,value)


This is a very ugly kludge, and there are aspects that may not work 100%
correctly.  What it does is stick a wrapper around your persistent object
which converts __getattr__ to try __getitem__ first.  The kludgy part is
that methods bound to the inner self will NOT have this getattr, as they
will not be bound to the wrapper, and thus during execution of such a
method, one must perform self[] calls to access these extended attributes.
This could be overcome with more coding to check for PythonMethod objects
and rebinding them as Acquisition.c does, but this is too complicated for
me to do off the top of my head in this e-mail.  :)