the order of running code in a decorator function - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: the order of running code in a decorator function (/thread-41090.html) |
the order of running code in a decorator function - akbarza - Nov-09-2023 hi in below code: # from:https://python.coderz.ir/lessons/l14-recursive- \ # functions-and-memoization-in-python.html def logger(func): print('Decorator is created!') def func_wrapper(number): print(f'New factorial call with parameter: {number}') result = func(number) print (f'factorial({number}) ==> {result}') return result return func_wrapper @logger def factorial(n): if n <= 1: return 1 else: return n #* factorial(n - 1) def test(): print("it is a test") if __name__=="__main__" : test() print(f"factoril(5) is : {factorial(5)}")I ran and debugged the above code in idle. the order of running lines was: 4,13,14,13,5,6,11,14,20,23,24,21,25,7,8,15,18,9,10 . the above code is a decorator function. why the order of running lines is as above line? plz, explain. thanks RE: the order of running code in a decorator function - deanhystad - Nov-09-2023 The factorial function is more interesting when it works. def logger(func): # 1 print(f"{func.__name__} wrapped by logger.") #2 def func_wrapper(number): #3 print(f"{func.__name__}({number})") # 4 result = func(number) # 5 print (f'==> {result}') # 6 return result # 7 return func_wrapper # 8 print("Decorating factorial") #10 @logger # 11 def factorial(n): # 12 if n <= 1: # 13 return 1 # 14 else: # 15 return n * factorial(n-1) # 16 print("Using the wrapped function") # 18 print(f"factorial(5) is : {factorial(3)}") # 19 The first two output lines: Show that the logger function gets called when we wrap the factorial function, not when the factorial function gets called at the end of the program. This code: @logger # 11 def factorial(n): # 12replaces "factorial" with "func_wrapper". When the program later calls "factorial(5)" it is really calling "func_wrapper(5)", The program calls "func_wrapper" here: print(f"factorial(5) is : {factorial(3)}") # 19So we begin executing func_wrapper's code. print(f"{func.__name__}({number})") # 4 result = func(number) # 5 print (f'==> {result}') # 6 return result # 7This line: result = func(number) # 5)calls "func" which is the original "factorial" function, so we start executing the original factorial function code: if n <= 1: # 13 return 1 # 14 else: # 15 return n * factorial(n-1) # 16When we get to this line: return n * factorial(n-1) # 16We recursively call the "factorial" function. But remember, the factorial function has been replaced with a call to "func_wrapper" so we find ourselves here: print(f"{func.__name__}({number})") # 4 result = func(number) # 5 print (f'==> {result}') # 6 return result # 7The end result is that the program lines are executed in this order: print("Decorating factorial") #10 def logger(func): # 1 print(f"{func.__name__} wrapped by logger.") #2 return func_wrapper # 8 print("Using the wrapped function") # 18 factorial(3) def func_wrapper(3): #3 print(f"{func.__name__}({3})") # 4 result = func(3) # 5 def factorial(3): # 12 if 3 <= 1: # 13 else: # 15 return 3 * factorial(2) # 16 def func_wrapper(2): #3 print(f"{func.__name__}({2})") # 4 result = func(2) # 5 def factorial(2): # 12 if 2 <= 1: # 13 else: # 15 return 2 * factorial(1) # 16 def func_wrapper(1): #3 print(f"{func.__name__}({1})") # 4 result = func(1) # 5 def factorial(1): # 12 if 1 <= 1: # 13 return 1 # 14 print (f'==> {1}') # 6 return 2 # 7 print (f'==> {2}') # 6 return 6 # 7 print (f'==> {6}') # 6 return result # 7 print(f"factorial(5) is : {6}") # 19 RE: the order of running code in a decorator function - akbarza - Nov-10-2023 (Nov-09-2023, 01:13 PM)deanhystad Wrote: thanks very much plz, replace factorial(5) with factorial(3). thanks again |