Python Forum

Full Version: problem In using functools in a code
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
hi
in code:
# from: https://python.coderz.ir/lessons/l13-decorator-generator-and-lambda-with-python-functions.html
import functools
import time

def timer(func):
    """Print the runtime of the decorated function"""
    #
    @functools.wraps(func)
    #
    def wrapper_timer(*args, **kwargs):
         start_time = time.perf_counter()
         value = func(*args, **kwargs)
         end_time = time.perf_counter()
         run_time = end_time - start_time
         print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
         return value
    return wrapper_timer


@timer
def waste_some_time(num_times):
     """This function only wastes some times."""
     result = 0
     for _ in range(num_times):
         for i in range(10000):
             result += i**2

if __name__=="__main__" :
    print(f" result of running command 'waste_some_time(1)' is :")
    waste_some_time(1)
    print()
    print(f" result of running command 'waste_some_time(999)' is :")
    waste_some_time(999)
    print(f"result of command 'waste_some_time.__name__' is: \
{waste_some_time.__name__}")
    print(f"result of  command 'waste_some_time.__doc__' is: \
{waste_some_time.__doc__}")
when a module is imported, for using its function, only the function is called. for example, I write:
import math
math.exp(1)
but in line 8 of the above code, there is @ functools.wraps(func). why this @is used for? I read about wraps a little value, but I did not understand it. for what we use this?
thanks
It is all explained in the documentation of functools.wraps() and functools.update_wrapper(). Have you read it?
(Oct-06-2023, 10:40 AM)Gribouillis Wrote: [ -> ]It is all explained in the documentation of functools.wraps() and functools.update_wrapper(). Have you read it?

hi
I did not see them, i will try read them.
thanks
(Oct-06-2023, 10:27 AM)akbarza Wrote: [ -> ]why this @is used for?
are you asking about decorators in principle or about this specific one?
(Oct-07-2023, 11:44 AM)buran Wrote: [ -> ]
(Oct-06-2023, 10:27 AM)akbarza Wrote: [ -> ]why this @is used for?
are you asking about decorators in principle or about this specific one?

i asked about@ sign in line 8.
(Oct-09-2023, 01:26 PM)buran Wrote: [ -> ]This (the @) is used for decorator syntax

check
https://peps.python.org/pep-0318/
https://realpython.com/primer-on-python-decorators/

hi
as you can see the timer, itself is a decorator and you say @functools.wraps(func) is a decorator again, namely decorator inside decorator?
Decorator means, there is a function, which takes a function and return a new function.
functools.wraps is a wrapper, and it copies from the original function the docstring, call-specs and some other stuff to the inner function. This is better for debugging.


def debug(func):
    def inner():
        print("Running func")
        result = func()
        print("Done")
        return result
    return inner


def test1():
    print("Hello")

test1 = debug(test1)
result = test1()

# The same with syntactical sugar
@debug
def test2():
    print("Hello")


test2()