If I create a decorator like following:
def my_decorator(some_fun):
def wrapper():
print("before some_function() is called.")
some_fun()
print("after some_function() is called.")
return wrapper
@my_decorator
def just_some_function():
print("Wheee!")
Another decorator can be defined as:
def my_decorator(some_fun):
print("before some_function() is called.")
some_fun()
print("after some_function() is called.")
@my_decorator
def just_some_fun():
print("some fun")
Both decorators will work the same. What is the benefit of using "wrapper" function inside decorator. I didn't get the purpose.
Decorators allow us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it. In Decorators, functions are taken as the argument into another function and then called inside the wrapper function.
Wrappers are used for two primary purposes: to convert data to a compatible format or to hide the complexity of the underlying entity using abstraction. Examples include object wrappers, function wrappers, and driver wrappers.
wraps() is a decorator that is applied to the wrapper function of a decorator. It updates the wrapper function to look like wrapped function by copying attributes such as __name__, __doc__ (the docstring), etc. Parameters: wrapped: The function name that is to be decorated by wrapper function.
Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated. Using decorators in Python also ensures that your code is DRY(Don't Repeat Yourself).
The purpose of having a wrapper function is that a function decorator receives a function object to decorate, and it must return the decorated function.
Your 2nd version of my_decorator
doesn't have an explicit return
statement, so it returns None
. When my_decorator
is called via the @
decorator syntax
before some_function() is called.
some fun
after some_function() is called.
gets printed, and then None
gets assigned to the name just_some_fun
. So if you add print(just_some_fun)
to the end of that code it will print None
.
It may be easier to understand what's going on if we get rid of the @
syntactic sugar and re-write your code using normal function calling syntax:
def my_decorator(some_fun):
print("before some_function() is called.")
some_fun()
print("after some_function() is called.")
def just_some_fun():
print("some fun")
just_some_fun = my_decorator(just_some_fun)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With