Analysis of Good Decorators

Analyze good decorators and learn how they're used in Python and popular libraries.

As a closing note, let's analyze good decorators to get an idea of how they're used in practice. Let's review some examples of good decorators and how they are used both in Python itself and in popular libraries. The idea is to get guidelines on how good decorators are created.

Traits of good decorators

Before jumping into examples, let's first identify traits that good decorators should have:

  • Encapsulation, or separation of concerns: A good decorator should effectively separate different responsibilities between what it does and what it is decorating. It cannot be a leaky abstraction, meaning that a client of the decorator should only invoke it in black-box mode, without knowing how it is actually implementing its logic.

  • Orthogonality: What the decorator does should be independent, and as decoupled as possible from the object it is decorating.

  • Reusability: It is desirable that the decorator can be applied to multiple types, and not that it just appears on one instance of one function, because that means that it could just have been a function instead. It has to be generic enough.

Decorators in the Celery project

A nice example of decorators can be found in the Celery project, where a task is defined by applying the decorator of the task from the application to a function:

Get hands-on with 1400+ tech skills courses.