PLEASE Use These 5 Python Decorators

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video I'll show you five python decorators that you need to know but first let's understand what a decorator is now a decorator is really just a function that modifies another function there's a bunch of built-in decorators in Python and we can also write our own now I want to look at an example of writing a custom decorator so we can understand what's actually happening behind the scenes when we use the built-in ones in Python so what we see here with the timer function is a decorator notice that what it actually does is return another function now we'll dive into that syntax in a second but let's look at how we use this what we do is we write the at symbol then the name of the function in this case it's timer and we decorate a function with it we put it on top of this function now you may have seen this in other modules like flask or Jango where we actually have these decorators to Define different roots and we use them all over python really behind the scenes they're functions that look something like this and what they do is take a function as their first argument and then return a new function that will replace this function seems a little bit strange but let's look at some equivalent syntax so rather than using The Decorator syntax here which is the at symbol what we can actually do is write the following line we can say the example function is equal to the timer function and then we can pass the example function to it when we do this this is effectively the exact same as simply writing The Decorator above the function I know seems a little bit strange but that's all it's doing it's simply taking this function right here passing it to this decorator and then replacing the function definition with whatever is returned from The Decorator so as you can see what the decorator really does is modify a function and typically add some Behavior around it in this case what the timer decorator will do is simply time how long it takes for a function to run so let's have a quick look at actually executing this code and then we'll dive into the syntax and understand how we write a custom decorator so let's start by running the code without decorating this function when I do that you see that we get the sum is and then this huge number now let's clear that and let's add our decorator so we'll say at at timer now when we run the code you'll notice that it tells us how long it took the function to run and then it tells us the sum now let's clear that and let's use that new syntax that I just showed you so rather than decorating the function we will say that the example function is equal to the timer and then we'll call the example function since this returns a new function we're just saying this function is now equal to a different one and now when I call this we'll get the exact same thing so that's what happens when we use a decorator now let's dive into this syntax so let's start with the first function here which is timer now notice that our decorator functions are always going to accept at least one argument or have one parameter which is the function that they're modifying so in this case we take in Funk and that means any fun function that we actually decorate with this decorator will be passed as the first argument this allows us to use this decorator for any type of function that we want then what we do is we write some kind of wrapper function inside of this function it might look like strange syntax but it's totally valid to Define functions inside of other functions in Python this is known as an inner function and there's some more complexities we don't need to get into that now within the wrapper function what we accept here is always star args and star star quarks now really what we're telling the function here is that we don't know how many arguments are going to be passed to it because this timer function could be used to decorate any function so we're going to accept any number of positional arguments and any number of keyword arguments if you've never seen this syntax before that's all it means except any number of positional arguments and any number of keyword arguments then what we do is we start a timer so this is our custom functionality that we're adding or decorating the function with so we start the timer by getting the start time we then actually call the function so we say the result is equal to the original function which was right here and then we pass to It Whatever the arguments and the keyword arguments were that were passed to this wrapper function we then figure out what the end time is and then we print how much time it took to run this function and then we return the result now the important thing is that we always want to be calling the function that we decorated we want to store whatever the result was and we want to return that result this way the decorated function will always work exactly the same as if it wasn't decorated except we've added some additional functionality right so in this case we're just starting a timer and seeing how long it took the function to run there's all kinds of advanced decorators and more use cases that we can look at but that's the basics of a decorator you write a function it accepts some function as the first argument it can accept other arguments but in this case we just accept one we have some wrapper function defined inside of it this wrapper function always accepts any number of positional and keyword arguments so it's Dynamic and can work for any function we add some additional functionality call the original function and then return whatever that result is now when I go and I use my decorator on top of any type of function it will work and it will allow me to add that timer functionality to it now if you want an entire video tutorial just showing you how to write custom decorators I'll link one on the screen but for now let's look at five built-in python decorators that you need to know about but first another thing that you need to know about is that even during this really tough job market the program that I run with course careers is still helping students land software development jobs we had a student complete the program in 39 days and in under a month later he landed a junior developer position making 70k per year if you want to learn more about how that works I have a free introduction course that you can check out from the link below there's a ton of value in there and even if you don't purchase the course it really breaks down what you need to do in 2024 and Beyond to qualify for these Junior developer positions because just being honest with you guys it is harder now than it was a few years ago but it's possible if you have the right guidance and you know the path you need to follow anyways check it out from the link below so the first deck rator we need to look at is known as property now this is used for various methods inside of a class and the idea here is that we can treat a method as if it was an attribute and we can gate the access to a specific field or attribute in Python now you may not know this but in Python we don't have access modifiers like private public and protected if you don't know what those are don't worry but in other programming languages we have a way to determine whether or not an attribute can be accessed from outside of the class in Python we don't have that so what we do as a convention is we add a leading underscore before any of the attributes that we defined inside of our instance that we don't want to be accessed outside of the class whenever you see something that starts with an _ that indicates that it should be treated as private and that means that I shouldn't come here and write something like C doore radius equals 10 even though I can do that we're denoting to the user of this class that we shouldn't do that and really this should be a private attribute now the reason that's important is that we typically use property in combination with a private attribute so that we can actually control the access of the attribute and whether you can set it delete it Etc so what we've done here here is we've written a method called radius all this does is return the value of the private attribute radius but we've denoted this as a property now when we do that that actually allows us to access the name of this method without calling the method from our Circle object so in this case I can say c. rius and that's actually going to call this radius method and return whatever is inside of it now just to show that to you if I say print called me here and I run this you'll see that it says called me and then we get five 10 then it says called me and we get 10 so the idea is we're going to go through this radius method every time we try to access the radius property now as well as a getter which is what this is known as we also have the ability to add a Setter now a Setter is what'll be used when we actually want to change the value of the attribute in this case we always use this private attribute as the source of Truth so what the actual value of radius is going to be and then we use the getter and the setter to control the axis for it so in this case we Define a Setter for our radius it takes in self and a value what we do is we make sure the value is positive and if it is then we actually set the radius which is our private attribute to be that value otherwise we raise a value error and we say that the radius must be positive so now when I come down here and I say c. radius is equal to 10 what will happen since I've used this decorator is I'll go into this method and I'll start executing the code inside of here so the value pass is going to be the value that I specified here which is 10 we're going to do our check since it's positive this will work and we'll be able to set the radius now let's see what happens if we try to set this to say something like -1 well when I run my code here notice we get an error and it says the radius must be positive because our Setter caught that this was a negative value and it didn't allow us to actually make that change to the private attribute so that's how the property decorator works that allows you to control access to a private attribute and to have some logic be handled or called when you're getting or setting a value now as well as getting in setting we can also add a deleter method so I've just slightly changed the example now to add the deleter method notice that the deleter method will be triggered whenever we use the Dell keyword so if I go here and I run my code we'll see that we get the output deleted the reason we're getting that is because we first print deleted we then delete the private attribute and now we would no longer be able to access access it now you can do anything you want inside of these methods but the idea is you define one of them as a property the name of the property is going to be the name of the method then you use whatever the method name is do Setter and. deleter to actually write your own custom Setter and deleter methods you don't have to implement them there's a few other options and things you can do here with properties but that's the basic idea and this is quite useful for creating read only attributes write only attributes or other custom Behavior to really gate the access to the private attributes and control what's happening with the internal state of your class so now we move on to a pretty popular decorator that you've probably seen before which is static method now the static method decorator is used when we want to denote a method inside of the class as static now a static method simply means it's something that belongs to the class and not to an instance of the class and it's not going to have any implicit first parameters like the self keyword or the class all that really means that we use the static method when we want to have some kind of function that belongs inside of a class but doesn't belong to a particular instance so maybe we have some math class and we have a function like add or multiply now it wouldn't really make sense for this to be associated with an instance we're not going to create an instance of this math class we're really just using the math class to organize a few different functions so that they're in a logical area and we know where to access them so this is a great example of where you would use a static method and you need need to decorate the method with the at static method decorator the reason you do that is you no longer need to accept that implicit first parameter like self or CLS now in this case the way that we would utilize these methods is by simply writing the name of the class however if you were to have an instance of the class we have something like m is equal to math you can still call these methods using the instance so I can say m. add one2 that's perfectly fine but what will happen since we've added this decorator is we'll no longer pass this instance as the first argument self allowing us to just treat these as static methods I don't have much more to say here just always use the static method decorator when you need a static method moving on now we have our class method decorator now again like the static method decorator this is used for a method inside of a class and what this will do is transform the first implicit parameter or argument here to be the name or instance of the class not an individual object so typically when you call a meth right you have that first parameter which is self so do something Define getor name self and then maybe we'd return something like the name of this person now when we use the class method decorator rather than getting access to the instance in which this method was called on we get access to the class so person itself now what that means is that we can only access attributes which are class attributes like the one defined here or other class or static methods so we can pretty much only access anything that's defined on the class not on the instance so again if we go here we can print the value of CLS and you'll notice that when I run my code here we get the class main doerson we don't get an instance of the class we get the class itself that allows us to access something like a class attribute and to access other class methods or static methods if this was a static method we wouldn't get anything and we would not be able to access this class attribute in summary use a class method decorator when you want to access class attributes or other class or static methods and use a static method decorator when the function is completely independent and it doesn't need to access anything else associated with the class or with the instance now moving on we're looking at a decorator from the funk tools module which actually has a few different decorators and this one specifically allows us to Cache the results of various function calls this is super useful when you continually make the same same call to a function especially in a recursive case like the one I'm going to demonstrate here so first let me just break down an example where we actually need this and then we'll look at how The Decorator works so here we have the Fibonacci function this is a very famous problem in computer science and the sequence that the Fibonacci function generates looks like this 1 1 2 3 5 8 Etc now if you haven't been able to catch on to the pattern the way it works is the first two values are one and then the next value is equ equal to the previous two values summ together so the basic idea is WR some Fibonacci function where it gives you the value of n so what the term n is equal to and the way you calculate that is by simply calculating what the previous term is and then what the second previous term is then adding those values together now what this involves in this simple implementation is continually calling the same function multiple times with the same value and the reason that's the case is because we get a recursive call stack that looks something like this so here's an illustration of the recursive call stack when we call the Fibonacci function with the value five keep in mind this is a recursive function again where we're calling n minus1 and n minus 2 now when we call the Fibonacci a five in order to calculate that we need the Fibonacci of four and we need the Fibonacci of three now in order to calculate the Fibonacci of four we're going to need to calculate the Fibonacci of three and the Fibonacci of two now in order to calculate the Fibonacci of two we need one and zero and you get the idea we're continually actually calculating the same values of Fibonacci exponentially more times as this value goes up so what we can actually do instead here is cache the results that we've already calculated so that we don't need to keep calculating them when we already know what the result is now what this will do is drastically increase the speed of our function and I'll show you an example of that right now so just as a simple illustration here I'm going to call the Fibonacci function here with a value of 40 now you'll notice that I don't actually get an immediate result and to be be honest with you I'm not sure how long this is going to take because this is a very very poor time complexity algorithm and we're going to run a lot of times continually doing the same computation that we've already calculated so you can see here even while I'm talking it still isn't finished and there you go it just finished now that took about 10 to 15 seconds and I want to show you what happens now when we add a simple cache so here's a modified version of the function now where we actually wrote in our own cache this is us doing it customly and you'll see see that when I run the code now we instantly get the result now let's see how we can do this in Python without having to actually modify the original function so we've gone back to the original example and what I can do now is I can simply decorate this with the funk tools. decorator now what this will do is actually write a custom cache for us and it will automatically resize the cache so we don't need to handle that ourself so Watch What Happens now when I run the code same thing we get the value instantly and we didn't need to write our own custom cache so whenever you're calling the same function repeatedly with the same arguments you can cache that result using the funk tools. cach without writing your own custom cache so now we are moving on to our final decorator which in my opinion is the coolest one and this one is the data class decorator now what the data class decorator will do is automatically fill in that boilerplate code that you're used to writing yourself now in order to understand the benefit of it let's look at the following class on our screen and then I'll show you how the data class decorator works it's also worth noting I made an entire video on this that goes through all of the details in intricacies if you want to learn more then check it out from the link in the description or the card on screen anyways let's have a look at this class so you can see here that what we're doing in this class is we're really just storing some information so we might have a method right where we're calculating some cost but generally we're just storing a name price and quantity and then we're writing a representation method something you've probably seen before and we're writing a very basic equal method we can actually compare if two products are the same products are the same if they have the same name price and quantity now this is great we can write this out but python has actually realized that this is a very common convention and people quite often do what you see here so they've actually given us a shortcut to really avoid having to write all three of the methods you see here now that shortcut is using the data class decorator so let's transform this code using that convention so there we are we now have code that is exactly equivalent to what you saw at the beginning of this section where we now don't need to write the init repper or equal method they're actually automatically implemented for us now if you don't believe me I'll show you a quick demo executing it but the way this works is we import data class this is The Decorator from the data classes module we put this on top of our class and what it will now do is it will read through the different attributes that we've ridden with their type annotation so string float and int and it will automatically populate the anit repper and equal method for us it can actually do quite a bit more and it's very flexible in terms of how it works again I made an entire video on it but the idea is now all that boilerplate code that we' commonly have to write on our own will automatically be added for us so let's paste in a simple usage example so you can see how it works so I've just pasted in some simple usage here and you can see that when I run my code this works and we get the results that were shown on the screen the idea is our initialization is already written for us again we didn't write that but it's already implemented to handle the name price and quantity we then have the representation method so when we print out the product we get it in a human readable form we can call any of the original methods that were written on this class and then we can use the equivalents to check if these products are the same notice that P1 and P2 were the same because they had the same value for each of their attributes that is the data class decorator super cool and with that said that's going to wrap up this video I hope you guys enjoyed if you did leave a like subscribe and I will see you in the next [Music] one
Info
Channel: Tech With Tim
Views: 101,032
Rating: undefined out of 5
Keywords: tech with tim, Python, decorators, Python programming, coding tips, Tech with Tim, Python tutorial, Python functions, Python decorators tutorial, Python programming guide, coding in Python, software development, Python projects, Python programming tips, Python coding, coding for beginners, Python advanced, Python decorators examples, Python development, Python functions tutorial, artificial intelligence, ai, how to code in python, coding tutorial, programming basics
Id: JgxCY-tbWHA
Channel Id: undefined
Length: 20min 12sec (1212 seconds)
Published: Tue Mar 19 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.