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

Greg Ewing see at my.signature
Tue Jul 25 00:43:06 EDT 2000


Paul Prescod wrote:
> 
> 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.

It seems I made a mistaken assumption about why you
chose to tie the three accessor together. I can see
your reason now.

In my version, there would be flags in each class 
indicating whether it had any accessors of each of 
the three types, so classes without any accessors
would not be affected.

For classes with accessors, there would be an extra
dictionary access for an attribute with no accessor,
so it would be slightly slower than yours in that case.
But it would still be a lot better than the current 
situation with __getattr__/__setattr__, which incurs
a Python function call for every attribute access.

So as usual it's a tradeoff between simplicity and 
ease of use, and squeezing out the last ounce of speed. 
I'd rather see a simpler design even if it's a little
bit slower -- that seems to be the Python way.

If you're still interested, here are the gory details:

Each class has three flags: has_get_accessors,
has_set_accessors, has_del_accessors. These are set
whenever an appropriately-named method is added to
the class.

Each instance also has the same three flags. These are set 
at instance creation time if the corresponding flags are 
set in the class or any of its superclasses.

To get attribute attr_name:
   if attr_name is in the instance dict:
      return it
   else:
      if the instance's has_get_accessors flag is set:
         translate attr_name to interned get_accessor_name using cache
      for each class along the inheritance path:
         if the class's has_get_accessors flag is set and it contains
            a method called get_accessor_name:
               call it and return the result
         else:
            if the class contains an attribute called attr_name:
               return it
      raise AttributeError

To set attribute attr_name:
   if the instance's has_set_accessors flag is set:
      translate attr_name to interned set_accessor_name using cache
      for each class along the inheritance path:
         if the class's has_set_accessors flag is set and it contains
            a method called set_accessor_name:
               call it and return
   set attr_name in the instance dict

To delete attribute attr_name:
   if the instance's has_del_accessors flag is set:
      translate attr_name to interned del_accessor_name using cache
      for each class along the inheritance path:
         if the class's has_del_accessors flag is set and it contains
            a method called del_accessor_name:
               call it and return
   delete attr_name from the instance dict

-- 
Greg Ewing, Computer Science Dept, University of Canterbury,	  
Christchurch, New Zealand
To get my email address, please visit my web page:	  
http://www.cosc.canterbury.ac.nz/~greg



More information about the Python-list mailing list