It seems that the general consensus is that attributes are usually considered instantaneous and accessible after use, so if a calculation done as @property is expensive, it is probably best to either cache the result for repetition to use (@Martijn Pieters) or leave it as a method, since it is generally expected that methods will take longer than searching for attributes. PEP 8 Notes :
Note 2: try to maintain a side effect of functional behavior, although side effects such as caching are generally excellent.
Note 3: Avoid using properties for expensive calculation operations; attribute notation makes the subscriber believe that access is (relatively) cheap.
One specific use case for the @property decorator is to add some behavior to the class that does not require class users to change foo.bar calls to foo.bar() calls - for example, if you want to count the number of times the attribute referred to, you you can convert the attribute to @property where the decorated method manages some state before returning the requested data.
Here is an example of the source class:
class Cat(object): def __init__(self, name): self.name = name
Using the @property decorator, we can now add some machines under the hood without affecting the user code:
class Cat(object): def __init__(self, name): self._name = name self._name_access_count = 0 @property def name(self): self._name_access_count += 1 return self._name
This processing of the @property decorator is mentioned in some blog posts ( 1 , 2 ) as one of the main use cases, allowing us to write the simplest code first, and then move on to the methods decorated with @, if necessary.
source share