[Tutor] Regarding Python api script

Steven D'Aprano steve at pearwood.info
Fri Dec 7 23:33:56 EST 2018


On Fri, Dec 07, 2018 at 12:30:18PM -0500, Avi Gross wrote:

> #  > I have often seen something like this done with methods, such as to
> #  > emulate decorator functionality where a method is created in an 
> #  > object with a name
> #  > and the very next method created has the same name with the same
> #  > function name as an argument to replace it.
> #  

Then I asked:

> # I don't understand this. Can you show an example? Even if made up?
[...]

And Avi explained:

> class classy(object):
>     ...
>     # Original function first of this name
>     def recreational_fun(args):
>         ...
> 
>     # New function, second of this name
>     recreational _fun = timing_is_everything(recreational _fun, args)

Ah, now I understand!

That's a decorator. The only difference is that it predates the 
introduction of *decorator syntax* using the @ symbol.

The *decorator design pattern* is an idiom which uses a wrapper function 
to add functionality to an existing function. Given a language where 
functions are first-class values, you can pass a function to another 
function as argument, and return yet a third newly constructed function. 
So this gives us the decorate pattern. In pseudo-code:

# Decorator pattern
def decorate(input):
    output = wrap input with extra functionality
    return output

new_function = decorate(function)

But if you don't need to keep both the old and new versions of the 
function, you can just write this:

function = decorate(function)


https://en.wikipedia.org/wiki/Decorator_pattern

In Java, it is more common to apply the decorator pattern to instances 
rather than functions or classes, but the principle is the same. Even if 
Java makes something conceptually simple incredibly complex :-)

*Technically* speaking, such a design could have been used in Python 
going all the way back to Python 1.4 or older, since functions have 
always been first-class values. But it only got really useful from about 
Python 2.2, with the introduction of closures to the language, and the 
classmethod and staticmethod decorators.

But initially, we didn't have dedicated syntax for applying a decorator, 
and had to write:

def function():
    ...

function = decorate(function)


which repeats the function name three times. It wasn't until 2.4 that 
the @ syntax was approved:

@decorate
def function():
    ...


which is literally syntactic sugar for the original version.

See PEP 318 for the background:

https://www.python.org/dev/peps/pep-0318/




-- 
Steve


More information about the Tutor mailing list