More Considerations for Using Descriptors

Learn how to avoid code duplication using descriptors, and alternatives to using class decorators.

Here, we'll discuss general considerations for descriptors in terms of what we can do with them, when it is a good idea to use them, and also how things that we might have initially conceived as having been resolved by means of another approach can be improved through descriptors. We will then analyze the pros and cons of the original implementation versus the one after descriptors have been used.

Reusing code

Descriptors are a generic tool and a powerful abstraction that we can use to avoid code duplication.

A good scenario where descriptors might be useful is if we find ourselves in a situation where we need to write properties (as in a method decorated with @property @<property>.setter or @<property>.deleter), but we need to do the same property logic multiple times. That is, if we needed something like a generic property, or else we'll find ourselves writing multiple properties with the same logic and repeating boilerplate. Properties are just a particular case of descriptors (the @property decorator is a descriptor that implements the full descriptor protocol to define its get, set, and delete actions), which means that we can even use descriptors to accomplish far more complex tasks.

Another powerful type we have seen for reusing code was decorators. Descriptors can help us create better decorators by making sure that they will be able to work correctly for class methods as well.

When it comes to decorators, we could say that it is safe to always implement the __get__() method on them, and also make it a descriptor. When trying to decide whether the decorator is worth creating, consider the three-problems rule we stated before, but note that there are no extra considerations toward descriptors.

As for generic descriptors, besides the aforementioned three-instances rule that applies to decorators (and, in general, any reusable component), it is advisable to also keep in mind that we should use descriptors for cases where we want to define an internal API, which is some code that will have clients consuming it. This is a feature oriented more toward designing libraries and frameworks, rather than one-time solutions.

Get hands-on with 1200+ tech skills courses.