Decorators and Clean Code

Now that we know more about decorators, how to write them, and avoiding common issues, it's time to take them to the next level and see how we can leverage what we've learned to achieve better software.

We briefly touched on this subject previously, but those were closer-to-the-code examples, as the suggestions referred to how to make specific lines (or sections) of the code more readable.

The topics discussed from now relate to more general design principles. Some of these ideas we have already visited previously, but the outlook here is to understand how we use decorators for such purposes.

Composition over inheritance

We have already discussed briefly that, in general, it's better to have composition rather than inheritance because the latter carries some problems of making components of the code more coupled.

We previously introduced the idea of using the magic method __getattr__ to resolve attributes dynamically on objects. We also gave the example that this could be used to automatically resolve attributes based on a naming convention should this be required by an external framework, for example. Let's explore two different versions of solving this problem.

Placing __getattr__ into the base class

For this example, let’s assume we’re interacting with a framework that has the naming convention of calling attributes with the prefix resolve_ to resolve an attribute, but our domain objects only have those attributes without the resolve_ prefix.

Clearly, we don't want to write a lot of repetitive methods named resolve_x for every attribute we have, so the first idea is to take advantage of the aforementioned __getattr__ magic method, and place it in a base class:

Get hands-on with 1200+ tech skills courses.