<p>All a decorator does is it allows you to build upon your function in some way i.e. it's a higher-order function. Ultimately, I prefer explaining them by &quot;unrolling&quot; the decorator.</p>
<pre class="lang-py prettyprint-override"><code># This:
@decorator
def foo(...):
    ...

# Becomes this:
def _foo(...):
    ...

def foo(...):
    ...
</code></pre>
<p>You can also express the same logic using OOP.</p>
<pre class="lang-py prettyprint-override"><code>from abc import ABC, abstractmethod


class Decorator(ABC):

    def foo(...):
        ...

    @abstractmethod
    def _foo(...):
        ...


class Foo(Decorator):

    def _foo(...):
        ...
</code></pre>
<p>Inheritance makes sense in this case because you're essentially encapsulating logic that subclasses share. This example doesn't always work because you might want to use different method names for example, but concept is definitely there, and there's more sophisticated ways you can work around it all.</p>
<p>Ultimately however, decorators are higher-order functions. With that, I would suggest exercising them with some restraint, remembering that higher-order functions are for when you need the function itself and cannot separate the logic from it.</p>
<p>Common examples where using decorators might overcomplicate things in my experience include:</p>
<ul>
<li>Pre-/post-processing e.g. input checking, which should just be a function call at the start/end(s) of your function.</li>
</ul>
<pre class="lang-py prettyprint-override"><code># Turn this:
@type_check
def foo(...):
    ...

# Into this:
def foo(...):
    type_check(...)
    ...
</code></pre>
<ul>
<li>Treating the function call like a block of code e.g. for timing, which can be done using <code>with</code> blocks instead.</li>
</ul>
<pre class="lang-py prettyprint-override"><code># Turn this:
@timed
def foo(...):
    ...

# Into this:
def foo(...):
    with Timer():
        ...
</code></pre>
<p>Decorators are good for cases where the function being decorated is itself necessary, such as a function which needs to be saved to an API library that will call it for your API.</p>

CC BY-SA 4.0
2022-05-06T05:57:56.900Z
2022-05-06T05:57:56.900Z
Simply Beautiful Art
<p>You already said it yourself, the Python decorator is just syntactic sugar for a <a href="https://en.wikipedia.org/wiki/Higher-order_function" rel="nofollow noreferrer">high order function</a>. When more than one decorator is applied, like in the example below, we could say it is also a kind of <a href="https://en.wikipedia.org/wiki/Function_composition" rel="nofollow noreferrer">function composition</a></p>
<pre><code>@f1(arg)
@f2
def func(): pass
</code></pre>
<p>is equivalent to</p>
<pre><code>def func(): pass
func = f1(arg)(f2(func))
</code></pre>
<p>The Python <a href="https://peps.python.org/pep-0318/" rel="nofollow noreferrer">PEP 318</a> where this feature was originally presented, mentions that:</p>
<blockquote>
<p>There’s been a number of complaints about the choice of the name ‘decorator’ for this feature. The major one is that the name is not consistent with its use in the <a href="https://web.archive.org/web/20031204182047/http://patterndigest.com/patterns/Decorator.html" rel="nofollow noreferrer">GoF book</a>. The name ‘decorator’ probably owes more to its use in the compiler area – a syntax tree is walked and annotated. It’s quite possible that a better name may turn up.</p>
</blockquote>
<p>A decorator is just a pattern, what matters usually is the intent. In object-oriented languages, you would implement it with a class decorator, and in functional languages, you'd resort to a function decorator.</p>

CC BY-SA 4.0
2022-04-27T22:19:09.610Z
Actually, if the decorator function invokes the decorated function then it is actually quite close to GoF usage, though there the emphasis is on objects and interfaces.
Buffy
CC BY-SA 4.0
2022-04-28T04:43:54.887Z
@Buffy a function is just an object with a single method, the simplemost interface :-)
Bergi
CC BY-SA 4.0
2022-04-27T21:39:10.727Z
2022-04-28T03:47:43.407Z
2022-04-28T03:47:43.407Z
Edwin Dalorzo
<p>As a python interested guy i have seen the syntactic sugar of a decorator like this:</p>
<pre><code>@decorator
def decorated_method(self):
    return &quot;Hello&quot;
</code></pre>
<p>So, it's a sort of higher order function in python, but my question is:
Are there other patterns or ways to express the same idea of decorating beyond idiomatic python features, some more general concept under the computer science field?</p>
<p>Once upon a time in a nodejs course, the teacher mentioned &quot;function decorations&quot; but i didn't make sense of it clearly. Regards!</p>

<programming>
How can i explain the concept of decoration from the computer science perspective
# How can i explain the concept of decoration from the computer science perspective

(Asked by: username_0 on 2022-04-27)

As a python interested guy i have seen the syntactic sugar of a decorator like this:
@decorator
def decorated_method(self):
    return "Hello"

So, it's a sort of higher order function in python, but my question is:
Are there other patterns or ways to express the same idea of decorating beyond idiomatic python features, some more general concept under the computer science field?
Once upon a time in a nodejs course, the teacher mentioned "function decorations" but i didn't make sense of it clearly. Regards!

**Tags:** programming


---

## 2 answers

### Answer by username_2 on 2022-04-27. Score: 3

You already said it yourself, the Python decorator is just syntactic sugar for a high order function. When more than one decorator is applied, like in the example below, we could say it is also a kind of function composition
@f1(arg)
@f2
def func(): pass

is equivalent to
def func(): pass
func = f1(arg)(f2(func))

The Python PEP 318 where this feature was originally presented, mentions that:

There’s been a number of complaints about the choice of the name ‘decorator’ for this feature. The major one is that the name is not consistent with its use in the GoF book. The name ‘decorator’ probably owes more to its use in the compiler area – a syntax tree is walked and annotated. It’s quite possible that a better name may turn up.

A decorator is just a pattern, what matters usually is the intent. In object-oriented languages, you would implement it with a class decorator, and in functional languages, you'd resort to a function decorator.

> **Comments:**
> **username_3**: Actually, if the decorator function invokes the decorated function then it is actually quite close to GoF usage, though there the emphasis is on objects and interfaces.  
> **username_4**: @username_3 a function is just an object with a single method, the simplemost interface :-)  

---

### Answer by username_1 on 2022-05-06. Score: 1

All a decorator does is it allows you to build upon your function in some way i.e. it's a higher-order function. Ultimately, I prefer explaining them by "unrolling" the decorator.
# This:
@decorator
def foo(...):
    ...

# Becomes this:
def _foo(...):
    ...

def foo(...):
    ...

You can also express the same logic using OOP.
from abc import ABC, abstractmethod


class Decorator(ABC):

    def foo(...):
        ...

    @abstractmethod
    def _foo(...):
        ...


class Foo(Decorator):

    def _foo(...):
        ...

Inheritance makes sense in this case because you're essentially encapsulating logic that subclasses share. This example doesn't always work because you might want to use different method names for example, but concept is definitely there, and there's more sophisticated ways you can work around it all.
Ultimately however, decorators are higher-order functions. With that, I would suggest exercising them with some restraint, remembering that higher-order functions are for when you need the function itself and cannot separate the logic from it.
Common examples where using decorators might overcomplicate things in my experience include:

Pre-/post-processing e.g. input checking, which should just be a function call at the start/end(s) of your function.

# Turn this:
@type_check
def foo(...):
    ...

# Into this:
def foo(...):
    type_check(...)
    ...


Treating the function call like a block of code e.g. for timing, which can be done using with blocks instead.

# Turn this:
@timed
def foo(...):
    ...

# Into this:
def foo(...):
    with Timer():
        ...

Decorators are good for cases where the function being decorated is itself necessary, such as a function which needs to be saved to an API library that will call it for your API.


---

