Hello guys.
So we are going to continue the discussion with respect to Python.
And in this video we are going to talk about an advanced concept in Python which is called as decorators.
First of all, we'll go ahead and understand or see the definition of decorators.
And then before understanding decorators, we also need to understand about two important topics that
is called as function copy and closures.
So once we probably understand this, then we will be able to understand very much easily with respect
to the decorators that we are discussing in this topic.
Now, before I go ahead, first of all, let us go ahead and check out the definition.
So decorators are powerful and flexible feature in Python that allows you to modify the behavior of
a function or class method.
They are commonly used to add functionality to functions or methods without modifying the actual code.
This lesson covers the basics of decorator and including and including how to create and use them.
Okay, so this is a basic definition.
You have to probably observe this keywords.
Uh, they they are commonly used to add functionalities to functions or methods without modifying the
actual code.
Okay, so first of all we will go ahead and discuss about function copy.
Then we'll go ahead and discuss about closures.
And then we'll get a complete understanding about decorators.
Now first let's go ahead and discuss about function copy.
Let's say that hey I am going to create a function which is called as welcome.
And here I'm just going to say hey let's go ahead and return okay.
Let's say welcome.
Welcome to the advanced Python course.
Okay.
Advanced Python course.
I'm just going to define this okay.
Now if I go ahead and call this welcome class welcome method.
Sorry I will be able to get this message.
Now what does function copy basically mean.
Let's say that I go ahead and create a variable.
And I will go ahead and assign this particular welcome method over here.
Now if I go ahead and execute well okay.
So it shows that hey it is a function.
And here I have actually done a copy of this particular function over here.
And can I run this same function over here with this.
If I use the braces you'll be able to see that I will be able to get my entire code.
Welcome to the Advanced Python course.
So in short, function copy basically means I can copy one function to the other function.
And here I will also show you something.
I will just go ahead and delete the above welcome method okay.
So let me just go ahead and delete this.
Now if we are deleting it you will be able to see that once.
I probably go ahead and delete it.
This function will get deleted okay.
I don't have to use even parenthesis for this.
And then even though I delete it, will I be having this welcome or this well variable or well function
that I've actually created by copying it?
Will it work same or not?
Okay, so if I go ahead and execute it here, you'll be able to see that I am able to get the code that
is welcome to the Advanced Python course.
So let me just go ahead and print this also okay.
And let me just go ahead and print this also.
Now do two times I should be able to print it even though I delete it okay.
So first of all I'm just going to create the welcome class again a welcome method again.
Now let me do this where I have saved the way I have done the copy of this particular function into
this particular variable.
Well, and now this becomes a function.
So I'm printing it.
Then I'm deleting the welcome method which had actually created initially.
Then I'm trying to print it whether it will be there or not.
We'll try to see.
So both the times we are able to see that hey welcome to the Advanced Python course is basically getting
visible.
So in the case of function copy you can copy one function to the other function.
And after that with respect to the reference function or the function that you have over here.
If you are deleting it also, then also you'll be able to see that that variable will have a new function
altogether, right.
Or whatever function I have actually created.
So this is one example with respect to the function copy okay.
Now let me just talk about one very important topic which is basically called as closures.
Okay.
Now what are exactly closures.
Closures are nothing.
But if you have probably seen other programming languages like C sharp, I was I have also worked in
C sharp, I have worked in Java.
So their closures basically means a function inside a function.
Okay.
So let's say that I will go ahead and create one function over here.
Okay.
So let's say I will go ahead and write definition main underscore welcome.
And here I'm going to give some kind of message.
Okay.
Let's say I'm giving some message.
Okay.
And let me do like this I'll not give message over here I'll just say message over here as I'll assign
it to welcome.
Okay.
Now as I said, closure is not about it's it's like a function can have another function within them.
Okay.
So I will just go ahead and define a sub welcome method.
Okay.
So I'll just go ahead and define the sub welcome method.
And this time let's go inside this particular method and print some message.
So I will say hey welcome to the Advanced Python course.
Okay advanced Python course.
And here I will just use some quotes over here.
Welcome to the Advanced Python course.
Okay perfect.
So till here we are very much good to go.
So I have just written a print statement.
Now let me just go ahead and again write another print statement over here and I'll say, hey, please,
uh, learn this concepts properly.
Okay.
So this is my message that I'm actually displaying.
Okay.
And then, uh, this will be my sub method.
Now, what I will do is that for the parent method over here, which I have like main welcome, I will
just go ahead and write return nothing but sub welcome method okay.
So I'm basically returning this particular method the sub method that we have basically defined.
Okay.
Now if I just go ahead and call this main underscore welcome.
And if I execute it.
So here you can see main underscore welcome.
Uh is not defined.
Why.
Uh let's see main underscore welcome sub welcome.
So let me just go ahead and execute it I have not executed that.
Now if I go ahead and execute it here, you can see that once I execute this particular method I will
be able to get the sub welcome.
Because see I'm returning the sub welcome method over here.
So this in turn will get printed right.
So that is the reason you will be able to see that.
Welcome to the Advanced Python course is getting displayed and please learn this concept properly is
also getting displayed.
Now this is fine, right?
Now here what I have done is that I have created a main method.
Inside that there is a sub method and the return type of this particular main method is nothing but
this particular method.
So when this method is called, you'll be able to see that this variable will be initialized.
And when we are trying to return this, it will go inside this particular method and it will display
all these results.
So that is how in a closure functions in a closure function, this is how the process with respect to
the execution actually happens.
But let me add some more very important things over here.
Now you can see that I have created this message variable.
Right.
And you know that this is a local variable for the main underscore.
Welcome.
But now the question arises can I access this particular variable inside this sub welcome method.
Right.
So in closure functions whenever I have a closure functions I can actually use this message variable
also which is defined inside the main method itself.
Right.
Main male underscore.
Welcome method itself.
So if I can just go ahead and write print message you'll be able to see that.
Now if I go ahead and execute it I will be able to see that okay.
This welcome is probably getting displayed.
So this means in a closure method, in a closure functions, anything that is defined outside the sub
method.
Right.
You can also access that within the sub method okay.
Not only that, let's say that I will just go ahead and remove this okay.
And here I will go ahead and write my message okay.
During the runtime.
And now what I will do is that here I will say hey welcome everyone.
So this will basically be my method.
And if I go ahead and call it um, it takes zero.
Okay.
I did not execute it.
So let me just go ahead and execute it.
Now if I go ahead and execute it here you can see welcome to the Advanced Python course then welcome
everyone.
So this print message is basically happening.
And you are able to see it over here.
Right.
So I hope you are getting an idea with respect to closures.
And this is what closures are all about.
You know, uh, so closure is nothing but a method within a method.
And here you can also see that whatever local variable I am creating inside the main method.
I will also be able to access this and remember, the return type is usually the sub method that we
have actually created over here.
Okay, now this is fine till here everything is probably working.
Now let me do one thing.
Okay, let me make some changes with respect to this closure function.
So I will just copy this entire thing.
I will paste it over here.
Now instead of just giving function I will try to give a function.
Sorry.
Instead of just giving a message, I will just try to give a function right.
And this function it will be an inbuilt function let's say okay.
And with respect to the function what I will do is that I will just call or I will just print whatever
things are basically coming in this particular function.
Now let's say I will just go ahead and call this function over here.
Okay.
Now let's go ahead and execute this.
Now this value that I'm actually giving is a function okay.
Now if I go ahead and call main underscore welcome.
And let's say I have an inbuilt function which is called as print.
Okay.
Let's say that I have an inbuilt function which is basically called as print.
Okay.
Now, if I go ahead and execute this here, you'll be able to see.
Welcome to the Advanced Python course is getting printed.
Please learn this concepts is also getting printed.
But here nothing is getting printed right.
But this print is an inbuilt function itself which will be printing anything, right?
So here inside this function I will pass some parameters.
I'll say welcome everyone to this tutorial.
Okay, now see if I go ahead and execute this.
What will happen.
So I will go ahead and execute over here and here also I will go ahead and execute.
Now what is basically happening.
This function is nothing, but it is a print method.
Right now this print is basically getting replaced over here.
And you know that if I am using an inbuilt function called as print, I can basically get replace.
The print will get replaced over here.
In short, we are writing this entire message over here.
That is nothing but welcome to everyone to this particular tutorial.
Right?
Not only this, you can again use different, different functions that you want.
Let's say that I want to use some inbuilt function called as length.
Okay.
Now I will just go ahead and print length.
Okay.
So let's say I will go ahead and write print uh, this specific function over here.
Okay.
This specific function over here.
Now I will just go ahead and execute it right now.
See?
See the magic okay.
See the magic with respect to this.
And here I'm just going to go ahead and write main underscore welcome.
And along with this I will provide a function keyword that is length.
And here let me just go ahead and define 123456 okay.
And let me just execute it.
So here you will be able to see that I'm getting an error in this right.
Int object is not callable.
So what I have actually given over here will check to this okay.
We will we will probably go ahead and see what kind of error is specifically coming over here okay.
So length of 1234 okay 1234.
So let's execute this particular code separately okay.
And let's see whether this will get executed or not.
So if I am executing this did I not close the brackets over here.
So this bracket is also closed.
This is also there okay.
so if I go ahead and execute this here, I'm able to get the value as six.
Now this same length function is probably going over here.
Instead of just giving the values over here.
Let me do one thing.
Okay I understood the mistake.
What is basically happening here.
We will go ahead and initialize the list.
Let's say the second parameter that I'm actually going to give is my list 12345 okay.
And let me just go ahead and write this list of elements over here.
List okay.
So let's say this is my second parameter.
Now if I go ahead and write list over here right.
This is what I really want to do.
I want to probably calculate the length of this specific list right now.
See whether I will be able to get the answer or not.
Right.
So here you can see mean welcome takes one positional argument, but two were given.
Uh okay.
I did not execute this.
Let's execute this particular method.
Now if I go ahead and execute it you can see.
Welcome to the Advanced Python course five is getting printed.
Why?
Because this function of list function of list is nothing.
But we are just trying to calculate the length of list.
Right?
And this is how you are able to get the value over here, right?
So this is the most important thing about closures.
You can probably define methods.
You can probably pass a method inside a method.
You can pass parameter as a method, you know, and you can probably use multiple things.
Right now let's talk about decorators.
If you have understood about closures and all.
Now it's time that we get an idea about decorators, okay?
And decorators will be something amazing, which you will definitely be able to understand.
Okay.
So let's, uh, let's do one thing.
Let's go ahead and probably start creating a decorator.
Okay.
First of all, I'll just do I'll just try to create a decorator completely manual okay.
So I'll go ahead and write or let me just go ahead and do one thing.
Let me copy this entire.
Entire code okay.
So instead of writing like this I'll just call this function right now.
In this case you will be able to see.
And I hope you have heard all about decorators in flask Django.
There are also a lot of decorators is basically used.
Okay, so this is what is my entire function.
Let's say okay.
Now I will go ahead and create my another custom method.
Okay.
So let's say I will say course underscore introduction okay.
And let's say I'm giving some kind of message over here.
Print.
This is an advanced Python course okay.
Advanced Python course.
Now if I go ahead and probably call this method then what will happen?
I will be able to get this message okay.
If I call this particular method and I give the parameter inside this as course introduction, then
what I will be getting.
So this function is going to just call whatever function I'm giving it over here.
And this is going to get printed.
And that is what we are actually getting it right now.
My main scenario is that without calling this function, can I make sure that I display all these messages?
And that is where decorators is used.
Okay, now see the magic, everyone.
This will be the most amazing thing.
So in order to create a decorator, I will be using at the rate symbol over here I will call my course
underscore introduction.
But along with this, at the rate I will just call this main underscore welcome class method.
Now as soon as I do this okay.
As soon as I specifically do this okay.
And let me just go ahead and write my entire definition of my course introduction, which is my method.
Now see what will happen.
This main underscore welcome.
You know what it is.
It is nothing.
But it is a separate method.
Right.
Which is taking a function as a parameter inside this.
And inside this there may be a some method which may be calling this particular function.
Now as soon as I wrote this as a decorator, a decorator keyword at the rate main underscore welcome.
And I am defining this entire function.
That basically means this function is going to get called inside this directly, and you will be able
to see the output that I am displaying.
Welcome to the Advanced Python course.
This is an advanced Python course.
Please learn this concepts properly.
What does this basically mean?
Whenever we write this as a decorator, that basically means this particular method is going inside
this as a parameter.
And whatever operations are there inside, we are just doing it right.
I hope you are able to understand this.
Now let's go back to the definition.
It says that they are commonly used to add functionality to a function or method without modifying the
actual code.
So here we are not modifying any of the code of main underscore.
Welcome.
It is completely generic.
It is taking a function over there and it is doing some kind of operation.
I am just adding this as a decorator on top of a function.
That basically means this particular function will be gone as a parameter to that, and it will be displaying
this where ever we are calling that specific function inside that particular main main method itself.
Right.
So I hope you are able to understand this, and I hope you are able to get a complete idea about decorators
itself.
Okay.
Now similarly, you can do multiple things with respect to this.
You can uh, try uh, multiple uh, like you can create different types of decorators, but always understand
the main thing is that you need to use this at the rate key keyword.
Right.
For creating that particular decorator.
Okay.
Let's see some more, uh, simple methods.
I will show you multiple examples over here.
Okay.
And then we will go ahead and understand more about this particular decorator.
Okay.
So this will be my second example with respect to decorator.
Okay.
So let's consider that I have a closure over here.
So I have a closure.
So here you can see my decorator with some function I have defined a wrapper class and saying print
something something is happening before the function is called.
Then there is a function that is getting called.
Then print something is happening after the function is called and we are just returning the wrapper.
We are returning this sub method right now.
Let me do one thing.
Let me just go ahead and execute this code.
Okay.
So here we have just executed it.
Okay.
So my decorator is there.
Now I will be using this at the rate my decorator.
Now if I really want to give my method okay.
My at the rate decorator okay.
If I really want to use this.
And let's say I go ahead and create a function which is called as say underscore.
Hello.
And I want to print something.
Right.
So here we will go ahead and print hello.
Right.
So here I'm printing.
Hello.
So once I probably just execute this right.
And now you'll be able to see that once I just say hey or once I probably call this particular method
that is say underscore hello say underscore hello.
You will be able to see that I'm able to get this right.
So here you can see that as soon as I call say hello.
So automatically based on this particular decorator.
For this decorator, this particular function is passed and it is getting printed everywhere, right?
All the things are basically getting printed.
Now let's try one more thing.
Uh, here I'm going to basically try something like decorators with arguments.
Okay.
So let's go ahead and try decorators with arguments.
And let's take one more example.
Okay.
So first of all please observe this particular code.
Okay so here I have definition.
Repeat I'm giving an n value.
Here I have another function okay.
And inside this I have another function.
Okay.
And here I'm giving star a args and star kw args.
This is nothing but positional and keyword arguments.
Then I'm saying for underscore I in range for underscore in range of n and I'm just calling that particular
function whatever function.
I'm actually going to provide it over here with respect to this arguments and kw args.
And for this particular function right, I have to probably uh return this with wrapper.
rapper.
So whatever rapper is over here and for this particular function you'll be able to see.
Sorry for this function that is decorator I'm returning rapper which is my sub function.
And for this function we are just returning decorator which is this particular function.
Now if and here you can see that I'm giving arguments right now I will go ahead and just call repeat
at the rate repeat.
And let's say I'm giving three value over here.
And let's say I go ahead and write definition say underscore.
Hello.
And this is my method that I'm actually going to call.
And let me just go ahead and write print.
Hello.
Okay.
So once I execute this over here now let's go ahead and just call this say underscore.
Hello.
So once I call this what is basically going to happen over here.
Very simple.
This repeat will take this three parameter.
Along with that it will take this function in the decorator itself wherever we are calling the function.
And then inside this wrapper it is just going to display this arguments with respect to the keyword
argument and positional argument.
So uh, if you probably see three times it is just going to print.
Hello.
Right.
Because three is the repeated number with respect to n.
So for I in range of zero comma three.
First time it is going to call this particular function which is nothing but print hello print hello
and print hello.
So if I go ahead and execute it here, you will be able to see that I am able to see the output.
Okay.
So this is something really amazing with respect to decorators right now.
Uh uh, if I probably say right decorator is something very advanced things you can specifically use
this for multiple purposes.
Uh, and as we go ahead, we'll be seeing multiple examples when we discuss in different, different
projects.
Right.
So I hope you are able to understand this video.
Finally, I would like to write some kind of conclusions over here.
So decorators are a powerful tool in Python for extending and modifying the behavior of function and
methods.
And you can read it over here just for your notes purpose.
Right.
So I hope you are able to understand it.
I hope I was able to probably discuss all the topics to make you understand about decorators.
So yes, this was it from my side.
I will see you all in the next video.
Thank you.