[Python-Dev] Fwd: Instance variable access and descriptors

Eyal Lotem eyal.lotem at gmail.com
Sun Jun 10 03:14:18 CEST 2007


On 6/10/07, Phillip J. Eby <pje at telecommunity.com> wrote:
> At 12:23 AM 6/10/2007 +0300, Eyal Lotem wrote:
> >A. It will break code that uses instance.__dict__['var'] directly,
> >when 'var' exists as a property with a __set__ in the class. I believe
> >this is not significant.
> >B. It will simplify getattr's semantics. Python should _always_ give
> >precedence to instance attributes over class ones, rather than have
> >very weird special-cases (such as a property with a __set__).
>
> Actually, these are features that are both used and desirable; I've
> been using them both since Python 2.2 (i.e., for many years
> now).  I'm -1 on removing these features from any version of Python, even 3.0.

It is the same feature, actually, two sides of the same coin.
Why do you use self.__dict__['propertyname'] when you can use
self._propertyname?
Why even call the first form, which is both longer and causes
performance problems "a feature"?


> >C. It will greatly speed up instance variable access, especially when
> >the class has a large mro.
>
> ...at the cost of slowing down access to properties and __slots__, by
> adding an *extra* dictionary lookup there.
It will slow down access to properties - but that slowdown is insignificant:
A. The vast majority of lookups are *NOT* of properties. They are the
rare case and should not be the focus of optimization.
B. Property access involves calling Python functions - which is
heavier than a single dict lookup.
C. The dict lookup to find the property in the __mro__ can involve
many dicts (so in those cases adding a single dict lookup is not
heavy).

> Note, by the way, that if you want to change attribute lookup
> semantics, you can always override __getattribute__ and make it work
> whatever way you like, without forcing everybody else to change *their* code.
If I write my own __getattribute__ I lose the performance benefit that
I am after.
I do agree that code shouldn't be broken, that's why a transitional
that requires using __fastlookup__ can be used (Unfortunately, from
__future__ cannot be used as it is not local to a module, but to a
class hierarchy - unless one imports a feature from __future__ into a
class).


More information about the Python-Dev mailing list