Returning Values From Decorated Functions
Return values from decorated functions don’t get returned by default unless the decorator allows it. In this lesson, you’ll see how to get return values out of decorated functions by making a small change to the decorator.
00:00 You passed arguments through your decorator—what about returning values from decorated functions? Let me show you an example. What happens to the return value of a decorated function? Well, it’s up to the decorator to decide what it’s going to do. Let’s take a look.
00:19
I started a new REPL session. From decorators
I’ll have you import again. Okay. Define the new function, decorating with @do_twice
.
00:32
Earlier, you set it up so the @do_twice
decorator can accept arguments. In this case, this function will print "Creating greeting"
and then return an f-string with the argument that was passed in.
00:50
Looks good! In this case, I’ll have you return it into a new variable, name it hi_adam
, and assign it by putting in the return_greeting()
function, "Adam"
.
01:06
This argument will pass in to the name
, and this should be returned into here. Great. What happens? It simply said Creating greeting
, Creating greeting
—doing it twice. Okay.
01:21
Let’s look at what’s going on with hi_adam
. Using a print statement on hi_adam
shows None
, and if you type the object’s name, it shows nothing also.
01:37 It looks like the decorator ate our argument and didn’t return it. How do you resolve that? Up here, inside the wrapper, change the second function to return the function being called. Let me repeat: you need to make sure that your decorator returns what’s being called, and it needs to be returned within the decorated function in order to return that value.
02:09 So, save. Then down here, I need to exit out and restart my REPL.
02:21
Okay. from decorators import do_twice
. Decorate your function the same way as last time, and this time when calling it…
02:42 Great. It looks like it returned it. So can you assign it to something?
02:50 Yep. It looks like it’s been assigned. And if you print it, that looks great. So, what did you change? By returning the value from our last function call, the decorated function gets back the value it was expecting.
03:10 You’re doing fantastic so far. One last little concept to cover and then on to some real-world examples. So up next, you’ll do a little bit of function introspection.
![Avatar image for Geir Arne Hjelle](/cdn-cgi/image/width=500,height=500,fit=crop,gravity=auto,format=auto/https://files.realpython.com/media/gahjelle.470149ee709e.jpg)
Geir Arne Hjelle RP Team on Sept. 1, 2019
Hi Mallesham
The None
comes from your spam_result_f()
function. It doesn’t contain a return
statement. For such functions, Python implicitly returns None
.
If you add something like return f"result is {res}"
after your prints, you should see the return value as well.
Mallesham Yamulla on Sept. 1, 2019
Ha got it. thanks for your response.. it’s really an awesome/ a very helpfull resource for learning decorators. thanks again.
Priya katta on March 12, 2020
Hi Chris,
could you please explain me this..
def decorator(func) def wrapper(args,kwargs): func(args, kwargs) return func(*args, kwargs) print(“This is printed after previous return”) return wrapper result = func(“some string”)
How does the statement after return gets executed?..
![Avatar image for Geir Arne Hjelle](/cdn-cgi/image/width=500,height=500,fit=crop,gravity=auto,format=auto/https://files.realpython.com/media/gahjelle.470149ee709e.jpg)
Geir Arne Hjelle RP Team on March 12, 2020
Hi Priya,
that statement will not get executed. If you need to do things in your decorator after calling the decorated function, you should store the return value in a variable:
def decorator(func)
def wrapper(args,kwargs):
func(args, kwargs)
value = func(*args, kwargs)
print(“This is printed after previous return”)
return value
return wrapper
result = func(“some string”)
Priya katta on April 14, 2020
Thank you!
Become a Member to join the conversation.
Mallesham Yamulla on Sept. 1, 2019
def spam_result_d(func): def wrapper_spam_res(args,kwargs): #func(args,kwargs) return func(args,**kwargs) return wrapper_spam_res
2. a function@spam_result_d def spam_result_f(res): print(‘checking for result’) print(f’result is:{res}’)
res_1 = spam_result_f(‘blocked’) print(res_1)
3. Output:checking for result result is:blocked–2 None
Here Could you please let me know why i’m getting None on printing it’s value res_1..?
I have followed your video on this concept , and there it’s giving an expected output..