Erm... might I suggest... (Re: New PEP: Attribute Access Handlers)

Michal Wallace sabren at manifestation.com
Mon Jul 24 13:13:40 EDT 2000


On Mon, 24 Jul 2000, Paul Prescod wrote:

> > 3. Doesn't magically put any names in the class dict that weren't
> >    explicitly put there by the programmer.
> > 4. As a consequence of 3, doesn't preclude having a real attribute with
> >    the same name in either the class or instance dict.
> 
> Then I can only presume that you look up the __get_?? method *first*
> before falling back to the "real" version. That will slow down plain old
> ordinary "gets" when there is no __get_?? method.


The two dict idea does make sense. You could have a __handler__ dict,
and then the normal __dict__. __dict__ would work as today, containing
normal values. __handler__ would contain accessor methods, marked as
being the special type to distinguish them from any other
methods... Or something else.

The "something else" could be any number of things:

1. "None", in which case you go look up the value again in __dict__
   (which I'd guess is a performance issue to your way of thinking)

2. A reference to the same value in "dict". This would mean you'd
   have to update both dicts, and keep them in sync.

3. A reference to a "default" accessor method (builtin), which 
   probably looks pretty much like the current getattr/setattr/delattr.


The dictionaries would look like this:

obj.__handler__={"__set_x_": Magic_Type_Pointing_To_set_x_Method}
obj.__dict__["x"] = "value for x"


__handler__ would be a special kind of dict. Sort of like this,
but built-in:

class HandlerDict (UserDict):
    def get(self, key):
         try:
            return self.data[key]
         except KeyError:
            if key[2:5]=="set":
                return old_setattr
            elif key[2:5]=="get":
                return old_getattr
            elif key[2:5]=="del":
                return old_delattr


You'd still have to look up the thing again in the other dict, but
you'd eliminate. Plus the handler dict could be copied directly when
inheriting, so it would always be a one step search to get the
handler, and the handlers would act only on __dict__.

---

I was going to suggest doing this as a mixin class, but the current
getattr/settattr/delattr doesn't seem to allow it when there's already
a value in the dict:

>>> class Model:
...    def __getattr__(self, key):
...        return 5
...
>>> m = Model()
>>> m.six = 6
>>> m.six
6
>>> m.five
5



Cheers,

- Michal
------------------------------------------------------------------------
www.manifestation.com  www.sabren.com  www.linkwatcher.com  www.zike.net
------------------------------------------------------------------------





More information about the Python-list mailing list