# Decorators in Python Decorator is a function, which modifies another function and returns it. The new function is often referred to as ==Decorated function==. > Why to use it ? Suppose we are passing our name as an argument to a function and we want a greeting before it, let's say Hello followed by the name, then we can simply modify the function and add a hello before it, that can be the easiest way. But in case when we are working on a big project, with many functions and we want a similar modification in all of it, then changing individual function would be a lot of task and it will also effect the readability. In such cases, using decorators is advised. > Before getting into the syntax of Decorators, it is important to know about how a function can be used in many ways. 1. Functions can be assigned to variable ![https://res.cloudinary.com/deujvj7up/image/upload/v1730209278/8c347c03-a5f8-4b5f-954a-93ff27937415.png](https://res.cloudinary.com/deujvj7up/image/upload/v1730209278/8c347c03-a5f8-4b5f-954a-93ff27937415.png) 2. Functions can be passed as an argument ![https://res.cloudinary.com/deujvj7up/image/upload/v1730209424/9bed2096-741f-4b21-9eb0-78362b57b995.png](https://res.cloudinary.com/deujvj7up/image/upload/v1730209424/9bed2096-741f-4b21-9eb0-78362b57b995.png) 3. Functions can be returned from another function ![https://res.cloudinary.com/deujvj7up/image/upload/v1730209533/31ddb5da-0157-4fb1-a135-6a2a3525ced8.png](https://res.cloudinary.com/deujvj7up/image/upload/v1730209533/31ddb5da-0157-4fb1-a135-6a2a3525ced8.png) ### Syntax Now as discussed above Decorators are used to modify an function. Lets get into the synatx of decorators with some coding examples. Suppose we want to add a greeting and a thank you test to an function :- ```python def greet(func): print("Hello") func() print("Thank You") @greet def hello(): print("viewer") ``` >This is same as writing the below code :- ```python def greet(func): print("Hello") func() print("Thank You") def hello(): print("viewer") greet(hello) ``` >in both the cases, the output will be the same. **output** Hello viewer Thank you >In a more detailed manner, we can also modify the code to return a function that is the modified function. ```python def greet(func): def mfunc(): print("Hello") func() print("Thank You") return mfunc @greet def hello(): print("viewer") hello() ``` >In case we are passing arguments, we need to pass them in the following manner :- ```python def greet(func): def mfunc(*args, **kwargs): print("Hello") func(*args, **kwargs) print("Thank You") return mfunc @greet def hello(a, b): print(a+b) hello(5,10) ``` **Output** Hello 15 Thank You ### Chaining Decorators It simply means decorating a function with multiple decorators. ```python def func1(func): def inner(): x = func() return x * x return inner def func2(func): def inner(): x = func() return 2 * x return inner @func1 @func2 def num1(): return 10 @func2 @func1 def num2(): return 10 print(num1()) print(num2()) ``` **Output** 400 200 The above code can be seen as :- print(func1(func2(num))) and print(func2(func1(num))). ### Practical Uses One common use of Decorators is to add logging to a function. For example, you can use a decorator to the arguments and return value of a function each time it is called. ### MCQ Questions 1. What symbol is used to decorate a function - ! - & - / - @ 2. Decorators modify a function - Temporarily - permanent - can't be determined - none of the above 3. Which of the following is true - Functions can be assigned to a variable - Functions can be passed as an argument - Functions can be returned from another functions - all of the above 4. What type of arguments are used to create general purpose decorators? - Positional - Arbitrary - keyword - default 5. Identify the decorator function in the below code: ```python def greet(func): print("Hello") func() print("Thank You") @greet def hello(): print("viewer") ``` - greet() - hello() 6. Find the output of the below code below code: ```python def greet(func): print("Hello") func() print("Thank You") @greet def hello(): print("viewer") ``` - Hello - Hello Thank You - Hello viewer Thank You - error 7. which of the following statements are true: statement-1: Nested functions are possible statement-2: Multiple decorators for a function can exist - Both statement -1 and 2 are true - statement -1 is true, statement -2 is false - statement -1 is falsr, statement -2 is true - Both the statemnts-1 and 2 are false 8. What’s the primary purpose of decorators in Python? - To change the return type of a function - To optimize the performance of a function - To modify the behavior of a function - To create new functions dynamically 9. Which statements about the the variables referenced and evaluated are true? ```python def reference(): def inner(): return 42 return inner def evaluation(): def inner(): return 42 return inner() referenced = reference() evaluated = evaluation() ``` - There’s no difference between the two. - The variable evaluated will be the integer 42. - The variable referenced will be a reference to a function object. - Neither referenced nor evaluated will hold the value 42. 10. What’s the purpose of the @ symbol when using decorators? - It unlocks a library of built-in decorators. - It increases code complexity. - It simplifies applying a decorator to a function. 11. You’ve decorated a function that accepts an argument, but when running it, you get an error: TypeError: wrapper() takes 0 positional arguments but 1 was given What might be a good approach to try to fix this error? - Using *args and **kwargs in the inner wrapper function - Creating separate decorators for functions with and without arguments - Removing the arguments from the function 12. Is it possible to define a decorator without an inner function? - Yes - No 13. Which of the following statements are true in regard to applying multiple decorators to a function? - The order of decorators doesn’t matter. - You can’t apply more than one decorator to a function. - You can apply several decorators by stacking them on top of each other. - The order of decorators matters. 14. How many functions should you define to create a decorator with arguments? - One - Two - Four - Three 15. Idenify the line with error: ```python def greet(func): print("Hello") func() print("Thank You") !greet def hello(): print("viewer") ``` - Line 1 - Line 3 - Line 5 - Line 6 16. Idenify the line with error: ```python def greet(func): print("Hello") func() print("Thank You") @greet def hello(): print("viewer") ``` - Line 1 - Line 3 - Line 5 - No error 17. Find the output of the following code ```python def func1(func): def inner(): x = func() return 2 * x return inner def func2(func): def inner(): x = func() return x * x return inner @func1 @func2 def num1(): return 10 @func2 @func1 def num2(): return 10 print(num1()) print(num2()) ``` - 200 400 - Error - 400 200 18. Which of the statements correctly interprets the below code ```python def func1(func): def inner(): x = func() return 2 * x return inner def func2(func): def inner(): x = func() return x * x return inner @func1 @func2 def num1(): return 10 print(num1()) ```` - print(func2(func1(num1))) - print(func2(num)) - print(func1(num)) - print(func1(func2(num1))) 19. The new function obtained after being modified by a decorator is termed as - Decorator function - Modified Function - Decorated Function - New Function 20. What will be the output of the following code? ```python def create_adder(x): def adder(y): return x+y return adder add_15 = create_adder(15) print(add_15(10)) ``` - 15 - 10 - Error - 25