New PEP: Attribute Access Handlers

Bjorn Pettersen bjorn at roguewave.com
Sat Jul 22 12:04:38 EDT 2000


Gordon McMillan wrote:
> 
> Bjorn Pettersen wrote:
> 
> >Paul Prescod wrote:
> 
> >> Actually, I'm not sure if my proposal would help here. Appending to a
> >> cStringIO is not an assignment operation...
> >
> >The only requirement was that the attribute access (myObject.property)
> >stay the same, only instead of returning a string it would compute
> >.value() on the cStringIO object. I.e., original:
> >
> >  class MyObject:
> >    def __init__(self,s):
> >      self.s = s
> >
> >new version:
> >
> >  class MyObject:
> >    def __init__(self,s):
> >      self._s = cStringIO.StringIO(s)
> >    def __getattr__(self, a):
> >      if a == 's':
> >        return self.__dict__['_s'].value()
> >      else:
> >        return self.__dict__[a]
> 
> Umm, that should be:
>   def __getattr__(self, a):
>     if a == 's':
>        return self._s.value()
>     raise AttributeError, a
> 
> (__getattr__ is last resort - not called if the attribute is found.)

Yes, I knew that, and it didn't work... I didn't investigate much, but I
think it might have been because the constructor really looked like:

  def __init__(self, **kw):
    self.__dict__.extend(kw)

not sure about that though...

> >> > Perhaps you should add a few words about why you chose __attr_XXX__
> >> > instead of __set/get/del_XXX__?
> >>
> >> That was actually the first proposal. But inheritance could get
> >> confusing if you inherited set without get or get without set etc.
> >
> >Hmmm... I'm not quite sure I understand...
> 
> Of course you don't! Because Paul forgot to tell you that the first
> proposal said that defining one or more of __set/get/del_XXX__
> automatically defines all 3, with default behavior of "you can't do that".
> So a base class defining __get_X__ and a derived class defining __set_X__
> will have the wrong semantics 50% of the time whichever way you choose to
> handle it.

Hey, I think I understand it now <wink>!  So the reason you need to
install _one_ attribute handler with either scheme is that XXX has no
relation to an actual attribute ("it is disallowed to have an attribute
named XXX in the same instance dictionary as a method named
__attr_XXX__.") It's therefore impossible to have a default set/get/del
handler with the common semantics of setting/getting/deleting the
attribute. Solving that problem by associating XXX with a 'real'
attribute can't be done since it would probably require new syntax, and
wouldn't always be desired... Am I close?

-- bjorn




More information about the Python-list mailing list