1

Im struggling to understand decorator with python. My understanding is here below;

At first, my_function_too(x,y) method will be defined as func in my_decorator(func) and then function_that_runs_func(*args,**kwargs) methods will be outputed.

1. What is the func in @functools.wraps(func) ?

2. Why do we need to write return function_that_runs_func and return my_decorator here ?

My friends explained that function_that_runs_func()method is going to replace my_function_too() method. But I could not understand what he is saying and why.

3. Would anyone please tell gently me what he is implying ?

CODE:

def decorator_with_arguments(number):
   def my_decorator(func):
       @functools.wraps(func)
       def function_that_runs_func(*args,**kwargs):
           print("In the decorator")
           if number == 56:
               print("Not running the function")
               return None
           else:
               print("Running the 'real' func")
               return func(*args,**kwargs)
        return function_that_runs_func
     return my_decorator
@decorator_with_arguments(57)
def my_function_too(x,y)
    print(x+y)

my_function_too(57,67)

OUTPUT:

In the decorator

124

Community
  • 1
  • 1
anonymous
  • 53
  • 1
  • 8
  • How much have you read about decorators? – wwii May 29 '18 at 14:23
  • 1) functools https://stackoverflow.com/questions/308999/what-does-functools-wraps-do – Druta Ruslan May 29 '18 at 14:24
  • 8
    That is one of the more complex applications of decorators. You should start with understanding how a decorator without arguments and without `functools.wraps` works. – mkrieger1 May 29 '18 at 14:26
  • 1
    [Decorator Basics (SO answer)](https://stackoverflow.com/a/1594484/2823755) - It's a long answer but it might give you a better feel for them. Play around with some simpler decorators. Here are a few (maybe not so simple) to peruse - [Python Decorator Library](https://wiki.python.org/moin/PythonDecoratorLibrary) – wwii May 29 '18 at 14:36

1 Answers1

0

It may help to think of a decorator that takes args as a decorator factory. So decorator_with_arguments(57) returns my_decorator, which does the actual decorating.

That is, my_decorator receives the original version of my_function_too as its arg and returns the decorated version, binding it to the name my_function_too, just as if you did

my_function_too = my_decorator(my_function_too)

In your code, the func in @functools.wraps(func) is the function that's passed to my_decorator, which in this case is the original version of my_function_too. functools.wraps is a decorator version of functools.update_wrapper. You can read about them both in the linked docs. Don't worry too much about them, they just make the decorated version of the function look more like the original version.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182