Python Class – Creating an Attribute of an Object Versus a Method

classpython

This question pertains to properly structuring a class. The object of a class I have is instantiated with multiple parameters. Many of these parameters are then manipulated with each other to derive new values. Currently, I have all of these manipulations as methods in the class.

Is it inappropriate to move these methods to attributes when I'm instantiating the object? There is a bit of a grey area regarding whether these new derivations are attributes of the object or a new output. In some cases, they definitely seem like mere attributes. For example, in addition to representing nominal values, I want to store the values as a percentage of their expected amount. This definitely seems like an attribute.

However, if I relegate this to __init__, then that strengthens the argument to relegate other methods that have more complexity.

Best Answer

Properly structured is subjective. :)

Generally, the more moving parts you have (i.e. mutable state), the harder it is to reason about your code. There are more pieces to fit in your mental model of the code, but there are additional concerns as well, such as ensuring the derived values stay coherent when a value is updated, or or that your code is correct if ran in a concurrent context. Therefore, I would consider leaving the calculation of the derived attributes in a method as a good default since it minimizes the state required.

Not all calculations are equal, however. It might be too computationally expensive to re-calculate the derived values every time they are needed (e.g. in a tight loop), at which time you might want to consider caching. The good thing is that if the computation is hidden in a method, caching simply becomes an implementation detail, leaving the rest of your code unaware of this optimization. If your use case warrants it, you may even use the Decorator pattern to implement this caching, decoupling the actual, interesting calculation from the technical details of caching.

More specifically for Python, you can define your derived value as a property instead of a method. You have the benefits of keeping the state to the minimum while still seemingly using an attribute (if that makes sense in your use case). That being said, a property is generally expected not to perform an expensive operation, so if that is your case, I would generally prefer to keep the method.

Related Topic