A limitation of Python properties

April 8, 2007

A periodically annoying limitation of Python properties on instances is that you cannot remove or replace a property. (You can implement del in your property, but this is not the same thing.)

This restriction exists because properties are actually attributes on the class, not attributes on the instances. Because of how attribute lookup works, you can't even sneak a replacement in through the instance's __dict__.

This means that you can't use properties to implement a highly efficient 'generate once and then cache the answer' instance attribute, where the first time you access obj.x the value gets generated and thereafter access to it goes at plain instance attribute speeds. This matters, because property access is about three times slower than accessing a simple attribute (and a plain function call to a lambda is about twice as slow).

If you need this, the best way is to make a __getattr__ function that creates the variable the first time it's accessed. This is somewhat less elegant and more monolithic than a property approach, and has the other downside that pychecker will probably complain about access to those magically created variables.

Sidebar: an interesting gotcha in timing attribute access

I did my timing of various attribute access cases using single-letter variable names. To my surprise, there were significant performance differences between the same access method based on what letter I used for the variable name. I suspect that this is because of dictionary hash collisions.

I also accidentally discovered that accessing class attributes is slightly faster than accessing instance attributes (and I don't think this one is dependent on variable names).

Written on 08 April 2007.
« Weekly spam summary on April 7th, 2007
Why indirect xdm probably doesn't work on your Linux machine »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Apr 8 22:23:25 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.