@paoloredaelli you can think decorators like mathematics function composition.
For example (a really silly one, but only to get the idea):
>>> import random
>>> import typing as t
>>> def g(f: t.Callable) -> t.Callable:
... def add_ten():
... return f() + 10
...
... return add_ten
...
>>> def f() -> float:
... """Return a random value in [0.0, 1.0)"""
... return random.random()
...
@paoloredaelli and
>>> @g
... def h() -> float:
... """I'm like f but with a new name and already decorated"""
... return random.random()
...
>>> f()
0.9379232620733947
>>> g(f)()
10.1676747637114
>>> h()
10.486860853177589
In the example above we are doing gāāāf. The @ syntax is just syntactic sugar.
This is the core concept, but usually decorators have a more practical applications like in the examples of your quoted article like performance measurement.
- replies
- 1
- announces
- 0
- likes
- 0
@paoloredaelli performance measurement, logging etc are only specific cases, you can apply decorators in a lot of use cases: every time you can compose your functions. But the core, as I said, it's just that: function composition. Decorators can accept parameters, you can make them more complex that in the silly example above. :) HTH