Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Simple Decorators

This lesson introduces decorators, functions that take other functions and extend their behavior without explicitly modifying them. You’ll see what decorators are and how they work. The examples in the lesson will also show you how to decorate your own functions.

HdVos on March 20, 2019

To me it feels uncomfortable to reuse “say_whee” here, because you loose the original function. I would feel more comfortable doing: say_whee2 = my_decorator(say_whee) Is it python convention to do it like in the video? say_whee = my_decorator(say_whee)

Of course it depends on the rest of your program, but why use a decorator when it is always used in the decorated way?

Geir Arne Hjelle RP Team on March 20, 2019

Hi HdVos,

As you’ll see in the next video, the conventional way of adding decorators in Python is by using the form @my_decorator like this:

@my_decorator
def say_whee():
    print("Whee!")

This is just “syntactic sugar” that is equivalent to the say_whee = my_decorator(say_whee) statement you’ve seen in this video. As you say, this may look a bit weird because you lose the (direct) reference to the original function. However, in most real world cases you are not really interested in the original function, which is why the @-notation works like that.

Instead, you want to use a decorator exactly because it adds some permanent behavior to your function. The main reason to use decorators is not that you want to turn on and off some behavior for a function, but rather that you want to add the same kind of behavior to many functions.

However, if you want to use decorators to choose a specific behavior, I think the easiest would be to not do the decoration (with either the @ form or reassignment like in this video). Then, you choose in your code whether you call

say_whee()

or

my_decorator(say_whee)()

Finally, a few words about the reference to the original function being lost: In later videos you’ll learn about @functools.wraps. It will be used in decorators like this:

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper():
        print("Before")
        func()
        print("After")
    return wrapper

This does several nice things, but one of them is that it keeps a reference to the original function:

>>> say_whee()
Before
Whee!
After

>>> say_whee.__wrapped__
<function say_whee at 0x7f61cafdebf8>

>>> say_whee.__wrapped__()
Whee!

Become a Member to join the conversation.