A similar question has been asked, but the OP compares the wrapper to a function without return, thus the answers focus on that "fault".
I understood decorators and why we use them instead of sub-classes after reading this article. There, they write the following example in which they introduce the need of the wrapper:
def uppercase_decorator(function):
def wrapper():
funct = function()
make_uppercase = funct.upper()
return make_uppercase
return wrapper
Yet, I can write "the same thing" (I'm expecting you to say it is not), this way:
def uppercase_decorator(function): #previously 'function' was called 'message' but 'function' is clearer for comparison.
make_uppercase = function().upper
return make_uppercase
Both versions could be applied to this fn, resulting in the same output ('HI ALL!') when calling salute()
:
@uppercase_decorator
def salute():
return 'Hi all!'
If main fn returns a random string (thanks to @wim for suggestion) one can notice that every time it runs it, the one without wrapper always returns the same thing when running the sayGarbage()
line:
def decorateIt(fn):
toUpper = fn().upper
return toUpper
def decorateW(fn):
def wrapper():
funct = fn()
toUpper = funct.upper()
return toUpper
return wrapper
import random, string
@decorateIt
def sayGarbage():
return "".join(random.choice(string.ascii_lowercase) for i in range(6))
sayGarbage()
Why is that so?