You can usually do this with caching. For example, you can write:
class Foo: def __int__(self, also, other, arguments):
So here we have the std property, but also the _std attribute. If the standard deviation has not yet been calculated, or you change the state of the object so that the standard deviation can change, we set _std to None . Now, if we turn to .std , we first check to see if _std None . If so, we calculate the standard deviation and store it in _std and return. Thus, if the object has not changed, we can simply get it later.
If we change the object so that the standard deviation can change, we return _std back to None to force a re-evaluation if we get access to .std .
If we change the state of the Foo object twice before repeating the standard deviation, we only recount it once. Thus, you can often modify the Foo object, and there are no additional costs (next to) (except for setting self._std - None ). Therefore, if you have a huge data set, and you are updating it a lot, you will only make an effort to calculate the standard deviation again, when you really need it.
In addition, it may also be an opportunity to update statistical measures in case it is (very) cheap. Say, for example, you have a list of objects that you often update in bulk. If you increase all elements with a constant, then the average value will also increase with this constant. Thus, functions that change state, so that some metrics can be easily changed, can update metrics, rather than create these None .
Note that .std is a property or the function does not matter. The user does not need to know how often this needs to be calculated. The std() function ensures that after its calculation, the second search will be quite fast.