hey guys welcome to the next blog on Python to tool for beginners in this blog I'm going to show you what our decorators in Python and also I'm going to show you how to use decorators in Python but before starting with this Blog I will suggest you to watch the last two blog in which I have talked about the basics of functional programming in Python so let's get started with the decorators so first of all what are decorators so decorators wraps a function and modify its behavior in one way or another without changing the source code of the actual function so let's see in practice how to declare and use decorators so first of all what I'm going to do is I'm going to define a very simple method and I'm going to name it as a say hello for example which doesn't take any argument and it just prints hello world let's say now let's say I want to decorate this function say hello and I want to print some kind of string before and after the printing of hello world without changing the code of the function so here we can declare that decorators so I'm going to declare a decorator function for this and I'm going to name it as decorator underscore func and this decorator function is going to take one argument and that this argument will be a function now we have seen in the last blog that we can return a function from a function or we can pass the function as an argument of another function so inside this function I'm going to declare one more function and I'm going to name it as wrapper functions which takes no argument and inside this wrapper function what I want to do is I want to call a function which is passed as an argument of the decor data function and then at last I just want to return this function so I'm going to just call return and I'm going to return the wrapper function without the parentheses so in the case of closures we have seen that we can return the inner function without the parentheses and that makes them the closures now let's say we are going to pass the say hello function as an argument of this decorator function and this function will be called here so in order to print something before and after this string hello world we can print something here also so here we can just write let's say we want to print X and we want to print this X 20 times let's say so we can just write this kind of notation and after the execution of function I want to print let's say Y 20 x so this is the simplest form of decorator which takes function as an argument now in order to call this say hello function with the decorator I am going to declare one variable and I'm going to name it as hello and then I'm going to call the decorator function and I told you that this decorator function takes the function as an argument so we can pass the say hello function as an argument to this decorator function which will be passed here and it will be called here now in the last blog in case of closures we have seen that because this decorator function is returning the inner function that means this variable will contain the inner function so we can call this hello with these parentheses and because this wrapper function doesn't take any argument so we can call it like this and let's run the code and let's see what happens so when we run the code you can see before the hello world string we have printed X 20 x and after the hello world we have printed I twenty times so this is a simple form of decorator and this is how you can use decorators in Python but Python also provides the simple way of declaring this kind of notation so instead of using this line of code I'm going to comment this line of code and also this line of code because instead of doing this you can use this kind of notation so just above your function in which you want to apply the decorator you use at the rate symbol and then the name of the decorator which you want to apply to the function and this notation above the function is equivalent to this kind of notation and now we can directly use this function say hello without the use of these two lines of code so let me run the code once again and let's see what happens and the result is the same so this is how the decorator works so let's go through the definition once again so decorators wraps the function and modify its behavior in one way or another without changing the actual code of the function so this decorator have changed the behavior of this function without even changing the actual code of this function now one question which may arise here is can we use more than one decorator with the same function so let's try to declare two decorator functions so we are going to declare two decorator functions and this decorator function I am going to name it as decorator X and the second function I am going to name it as decorator y so the first decorator function is going to decorate your function with the x value and the second decorator is going to decorate your function with the value Y so we are going to replace this by Y now here above your function you can use the decorator X and then also you can use the decorator Y above it so I'm going to just write at the rate decorator Y and this notation is perfectly fine so you can use one or more decorators with a single function so let me run the code and let's see what happens I'm going to run this code and you can see what happens so first of all the Y decorator has wrapped the function with Y's and then after that comes the X decorator which have decorated the function with X values and then your actual string is printed which is hello world now one thing to note here is the order of that decorator in which they are used so now we will try to just exchange the places of the decorator x and y and now let's run the code and let's see what happens so before it was printing y first and then the X when this decorator was used at the top and then the X decorator was used and now when we run the code the opposite of that will happen now if you want to see the equivalent notation of this using decorators so I'm going to just comment these decorators from here and let's try to use this kind of notation with our decorators so I'm going to just uncomment this code and this time what I'm going to do is I'm going to use this decorator x with the say hello and I'm going to enclose this notation inside that decorator Y so I can use this kind of notation which is equivalent to this kind of notation also so I'm going to run the code and you can see because decorator Y is the outermost decorator here it's going to just print the value of y and then we have the decorator X which is going to print the value of x and then our actual string if we exchange the places of decorator X and decorator why then the order of the printing will also change so now this was the very basic decorator example so let me remove this example and let me give you one more example so instead of using this function let me give you one more example so I'm going to declare a function called divide which is going to take two arguments let's say x and y and what it's going to do is it's going to return the value of the division of X divided by Y and let me remove these decorators from here so in the last say hello example over say hello function was not taking any argument and now we are giving our divide function to arguments that means we need to change the wrapper function here also so I'm going to name my decorator as decorator divided which takes a function and I'm going to change the wrapper function and now this wrapper function is going to take two values which is the value of x and y you can also write a and B it doesn't matter it just takes two values and instead of this kind of notation let me print the values of a and B first of all so inside this print function I'm going to just write divide and then we are going to pass the value of a comma and comma B so we are going to print the value of a and B and then we are going to check if the value of B is 0 or not so I'm going to just say if B is equal to 0 then we are going to print the message that division with 0 is not allowed and also we are going to return immediately from this function otherwise if the value of B is not equal to 0 then we are going to return the division of a by B so once again without changing the actual function which is divide we have changed the behavior of this function which is divided using this decorator function the last thing which we need to do here is to call our decorator function above our normal divide function and now I can use this divide function normally so I am going to just use this divide function inside the print and I'm going to pass two values here let's say 15 and 5 and let's run the code and it's going to print first of all this line which is printed using this statement which says divide a and B which is divide 15 and 5 and then because the value of B is not equal to 0 that means this value is returned with the result 3 which is the division of 15 by 5 now let's change the value of B and we are going to just give 0 as the value of B or Y here and I'm going to run the program once again and now you can see that this statement is printed which says the region with 0 is not allowed and because this function is not returning anything or you can return 0 from here it doesn't matter and I'm going to run the code it prints 0 here so this is how you can use decorators with the function which takes some arguments and return some values now let me give you one more real-world example which we can use with decorators so instead of our divide function now let's say what I want to do is I want to declare a function I'm going to just name it as my func which takes one argument or number so this will be a number and then this function calculates the sum of the number from 1 to the number which we provide here so let's say we provide 10 here so this function is going to give us the sum of the first 10 numbers and now I'm going to declare a variable called sum which I initialize it with zero and in the next line I'm going to use for I in some range and this range will be the number which is provided plus 1 because range starts from zero and not from 1 that's why I'm adding 1 here in the range if I want to calculate the sum of first 10 numbers let's say and if I provide 10 here then range will give you until 9 that's why I'm adding 1 here and then inside this for loop I'm going to just do some plus equals I and at last I'm going to just return the value of the sum now till now we have seen how to create decorator functions for the functions which takes no argument or for the function which takes some argument and we want to use these argument inside the wrapper function but at times you need to write a decorator function which will be a generic decorator function which means the decorator function which I'm going to create here will be used with not only this function but the other function which can take this argument on multiple number of argument or no argument so let's see how we can write a generic decorator function so let's say I want to measure the timing of this function how much time this function takes in order to execute this code and timings we can measure with any function so it doesn't matter that we need to use this function to calculate the timing you can also use the decorator function which I am going to create with the other functions also to measure the timing of those functions so because it's a timing decorator so I'm going to name it as timing and it takes once again the function as an argument and because we don't know which argument the function is going to take right now this function takes one argument but it doesn't matter you need to measure the time of the function which takes one argument or two argument or three argument or no argument so that's why in that case we can use this kind of notation Astrix odds here and then comma double Asterix kW args here and these two arguments makes your wrapper function independent of the number of argument which will be provided with this function and in order to calculate the timing of the function we need to import a module so let's import a module so I'm going to just write from time import time so there is an inbuilt time function which we can use to get the time and now under this wrapper what I'm going to do is I'm going to just declare a variable called start and I'm going to save the value of current time here so whenever you call this time with the parent says it's going to give you the current time now in the next line what I want to do is I want to just create a new variable which I will call it as result and I am going to assign the result of this function so let's call this function with the variables which we have provided into the wrapper function so because we don't know which argument comes with this function so we are going to just pass these argument as it is into the function argument which is passed as an argument of your decorator let's provide the indent here so this will be satisfied and then in the next line we are going to just print that time elapsed so I'm going to just say elapsed time and then this curly bracket and you already know we can call a format method on the string and here as an argument we just want to give the result of the start time and the end time so let's declare the end of time also after the function execution is completed we are going to measure the current time once again and then we are going to just say and the time which is stored in the end variable minus the start time and it's going to give us the time elapsed in the execution of dysfunction and at last because this function or the other function can also return some value at last we are going to return the result which we have calculated so I'm going to just write return this result so this is the generic timing function which you can use with any function whichever you like so I'm going to just decorate my function using at the rate the timing decorator and then I'm going to call this my function inside the print method so print my function and let's say I want to calculate the sum of first 20,000 values and I'm going to run the code and here in the result you will see zero point zero in the elapsed time because this value is very small and elapsed time is approximately equal to zero for the smaller values because we are just iterating over the smaller value but the sum is the exact sum so let's increase this value by two zeros and let's also print the value of start time and end time here so I'm going to just print the value of the end time and the start time so we know that what is the starting time and what is the ending time and I'm going to run the program once again and now you will be able to see that this is the starting time and this is the ending time and you will be able to see some time elapsed in the execution of this function and when I increase one zero here so you will be able to see two seconds is taken now for the calculation of the sum of this number so you can use this timing decorator in order to calculate the time of execution of any other function other than this also so this is how you can use decorators in Python I hope you've enjoyed this blog and I will see you in the next blog
إرسال تعليق