[Zope-dev] __getattr__ and Acquisition

Lennart Regebro lennart@torped.se
Wed, 25 Sep 2002 22:22:11 +0200


From: "Andreas Kostyrka" <andreas@kostyrka.priv.at>
> But my attributes are not normal. So I should generate them by
> __getattr__. Only by noticing that I could get the same effect by
> putting my attribute source in front of my object in the acquisition
> chain.
>
> The question is still, how does one a __getattr__ that needs (as a
> client) acquisition to calculate the attribute.

You don't. __getattr__ is used if you for example want data from a subobject
to behave like it's attributes directly on the object. Trying to get data
from another object in the ZODB to behave like they are attributes directly
on the object with __gettattr__ is problematic, because that is not what
it's designed for, and because in __getattr__ you don't have a context.

Making data from another object in the ZODB to behave like they are
attributes directly on the object is however exactly what Acquisition is
designed for, and hence it's easier to do it that way.

> (Basically __of__ works only if I do not need to know the attribute name

??? Why wouldn't it work if you know the attribute name? What it doesn't do
is to only work with some attributes, it works with all attributes, maybe
that is what you mean? This usually don't give you any negative side
effects.

> > I guess that depends on when you patch in the extra object in the
> > acquisition. If you do it in __of__() then I guess it's visible all the
>
> Well, where else can I patch it in?

Overriding __of__ means that you are changing how the acquisition chain
looks and behaves for the object. But you can also just wrap the object by
calling __of__ whenever you need it wrapped instead of overriding it.

If I remember the syntax correctly "foo = self.__of__(magickfolder)" would
wrap self in magickfolder, and make it acquire magickfolders attributes, so
that after doing this "foo.bla" would get the attribute from magickfolder if
it doens't exist on self. This you can do just before you need that
behaviour, and it will be a completely local behaviour.

Don't spank me if I don't remember all the details here, I haven't looked at
the code where we do this in a couple of months. :-) We insert our templates
in the acquisition chain when index_html is called, so that the correct
template is used when rendering. This insertion then only affects the
rendering.

From: "Dieter Maurer" <dieter@handshake.de>
>       "__getattr__" is used before acquisition comes into play.

You are probably correct. Nevertheless, you can't push acquired object into
the acqusition context in __getattr__, because the object inside __getattr__
has no context, and hence no objects are acquired. But of course it makes
sense that __getattr__ is called before the acquisition comes into play,
because otherwise you wouldn't be able to override acquired attributes. :-)