A limitation of Python properties
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).
Comments on this page:
|
|