Python Data Classes Are AMAZING! Here's Why

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
chances are that you've seen a class that looks something like this something pretty straightforward where you're just storing a few different values and maybe you have something like an equal method and a reer method in this case we have a two-dimensional point and we're just storing two values X and Y now what if I told you there was a way that we could eliminate writing all of these different methods and write this class in only four lines of code well if that sounds interesting to you then stick around and I'm going to share something that's really cool in Python which is data classes so let's Di into Data classes but first let's just run this code so we can get a look at what the output is and then compare it to when we use a python data class so all we do here is Implement a two-dimensional point we store the value X and Y in our representation method we print out what the point looks like so we have the X attribute and the Y attribute and then we have a way to compare these two points where we just check if the x value is the same and the Y Valu is the same we just have a little bit of output down here after we create two different points and you'll see that when I run the the code here we get our first point our second point and then the fact that these points are not equivalent because their X and Y values are different so now I'm going to write this class using a data class you'll get a sense of how that works and you'll see the difference so there we are we now have the exact same program it does the same thing you saw before and this class has the exact same functionality so let's run the code just to make sure this is indeed working and you can see we get the exact same output we got before but this time we didn't need to write any of that boiler play code like defining the initialization the reer method and the equal method this is the python data class decorator and what it does for us is actually fill in a bunch of methods that we typically have to write on our own it's super interesting and I'm going to share with you more about how it works in this video so let's begin by talking about what a data class is and what actually happened when we wrote these lines of code well this first line of code simply Imports the data class decorator from the data classes module and this was something that was added in Python version 3.7 it's somewhat new but the point is you don't need to install this it's something that's built into python now what this is called is a decorator a decorator is something that will modify what's defined below it so in this case we're modifying a class however we could be modifying a function or method and there's all kinds of other decorators in Python for example you may have seen the static method decorator before or the class method decorator before and there's all kinds of other ones that you can import from built-in python modules now in this case what the data class decorator will do is it will read the contents of our class and specifically it will focus on the different fields that we've defined now what we've done here is to find a field X and a field Y and we've given the type annotation that it's going to be of type int or the type hint in Python now these are known as fields and what the data class decorator does is read these and populate three common methods that typically we'd have to write on our own so in this case what it's going to populate is the anit repper and equal method methods now these are Dunder methods otherwise known as double underscore methods or magic methods which allow us to provide some special functionality to our python classes now starting with the init method this is something that's called when we create a new instance of our class so when we do something like P equals point we're going to call the anit method and then we need to provide any arguments or any parameters that are specified in AIT now what data class will do is it will read the different fields that we've defined and automatically specify those as mandatory parameters that we need to provide to the initialization so in this case I need to provide an X and A Y in that order because that's the order in which I defined these different fields so I need to pass something like one and two now it also implements a repper method now the repper method is something that will be called when we try to print out or view the contents of the object specifically in something like our terminal so if I go print P what we'll happen implicitly is we're actually going to call the wrapper method and then whatever that returns is what we'll output now as we we saw before the way that repper will be implemented is it will simply return a string that contains the name of the class so in this case it's point a set of parentheses and then inside the parentheses it will specify all of the field names as well as their corresponding value so we'll get something like Point X1 and then Y = 2 that's just the default implementation for repper and that's how it will be implemented when we use the data class decorator lastly it will implement the equal Dunder method the equal Dunder method is something we can use when we compare two instances of the same object so if I do something like P equals point and then P2 equals point the way that equal will be written is it will simply compare all of the different attributes for their direct quality so we'll see if the X's are the same and if the Y's are the same and if they are then it will go ahead and say these objects are equal so if I go p is equal to P2 like that and we run our code you'll see that we get the value true I apologize for the messy terminal so just a quick pause here for any of you that are serious but becoming software developers if you want to be like Max who landed a 70k per year job in Just 4 months of work consider checking out my program with course careers now this teaches you the fundamentals of programming but also lets you pick a specialization taught by an industry expert in front end backend or devops beyond that we even help you prepare your resume we give you tips to optimize your LinkedIn profile how to prepare for interviews we really only succeed if our students actually get jobs that's the entire goal of the program so if that's at all of interest to you we do have a free introduction course that has a ton of value no obligation no strings attached you can check it out for free from the link in the description so that's the absolute basics of the Python data class but there's a ton of other things that we can do so I'm going to show you a few examples now and go through some more advanced Behavior so the example you see now is directly from the python documentation and it shows you a slightly more complex class in this case we've actually implemented our own method which is totally fine we can write as many methods as we'd like and you'll notice that we have some type hints here so if you're unfamiliar with the syntax all we're doing is just adding some type hints which allow us to have some better autocomplete and understand what different methods and functions should be accepting or returning they're not actually enforced in Python which means you could return something other than a float but in this case we're just writing them out to kind of document how the code should look now what data class will do here is it will add those three methods we described so a knit repper and then the method now if you're curious what the inip method would look like it would look exactly like this so let me zoom out a little bit so that we can read it this is what would be generated by data class again this is right from the python documentation it's going to take all of the different fields that we've written out here so name unit price quantity on hand it's going to add the type hints for all of them and in this case you see that we have a default value so it's default equal to zero which means if I don't pass something for quantity on hand it's just going to be assign the value zero now it's worth noting here the data class has a ton of additional arguments that you can pass to it to modify how it works for example you can pass if we should generate the initialization if we should generate the repper the equal we have one for order we have a bunch of other arguments here and I'll leave a link to this documentation in case you want to check it out from below now one notable one you may be considering using is called order now what order will do is implement the ltle GT and GE methods which allow you to use the common arithmetic operators like the less than sign less than or equal to greater than Etc now the way this works is it will actually compare the different objects using a tuple of all of their field values we don't need to get into that in this video but in case you're curious I'll link this in the description now jumping back into the code here I want to show you an example that you're bound to run into if you use this frequently and that's having a mutable default parameter for one of your different field values now just to illustrate why this is an issue let's have a look at a common example here in Python so you can see that what I have have here is a simple function what we do is we have a list as the default value for the LST parameter now this is mutable meaning it can be modified uh and we will really be storing a reference to this list as opposed to a new instance of this list for every single call of the function now what that means is that when we print this out you're actually going to see that the list will be modified between function calls so when I run the code you can see that we get one and then we get one one now this is obviously an issue and this is a bad practice in Python that you need to avoid but how do we fix that when we're using the data class what if I want to do something like the different sizes that we have and I want this to be a list where we store maybe some strings well I can't simply assign this to a list because if I do that I'm going to get that same issue that we're seeing right here so how do I fix that well the way we fix that is by using a function that's provided from the data classes module now that function is called field and we can import it like this now it has a bunch of different param that we can pass to it what we're going to focus on here is the default and the default Factory so what I can actually do here is rather than specifying this as a normal list is I can write this as a field now within the field what I can do is I can pass to this something known as the default undor Factory and I can give this a function that should be called anytime we initialize a new instance of this class so this is now going to completely solve our problem and anytime we initialize a new instance of this class this default Factory function will be called and whatever it returns is what we'll use as a default value so we'll get a new list every single time not a reference to an existing list now if you do want to use this field and you don't want to have default Factory instead maybe you want to have a literal value that is immutable you can actually just specify a default and if you specify a default you can pass a value say like this now in this instance we'll get the same issue as before because this is a mutable default value however this is another parameter that you can pass to field now with field there's a few other things that we can specify here as well for example we can indicate whether or not we want it to be included in the initialization in the representation in our compare methods so things like equals less than greater than Etc and those are the main ones to take note of so for example maybe we don't want this to be included in the initialization then we would say a nit equals false and now it's not going to be something that we need to pass when we have that anit method now just as a quick side note here if you're curious what the code generated by this decorator will look like you can use the help function and pass the name of your class so I can say help inventory item and now when I run my code if I look in my terminal I can actually see all of the different definitions of my methods so for example I have my Constructor here it's specifying all of the different things then I have my methods like equal a knit repper Etc just something interesting in case you wanted to see that so now we're going to move on and discuss something you've probably had a question about and and that is how do I define a class variable when I use the data class decorator well to do that we can simply import the class VAR typing from the typing module we can then come here and Define something like class variable we'll give the typeint as the class VAR and then inside of here we'll specify what we actually want the type of the variable to be this could be something like an INT and we can make this equal to 100 now when we do that data class will actually recognize that this is a class variable because it will read the fact that this is a class far and it will not include it in any of the methods that it generates so it won't put it in the init the repper or any other one that it's making it's simply going to ignore it because it's a class variable so now we're moving on and we're talking about inheritance now in this example we have a data class that is inheriting from a non data class now when that's the case the initialization that's written by default from the data class decorator is not going to call the initialization of the base class so this is something that we need to do manually and we can Implement that by writing the post AIT Dunder method so when I write the post AIT Dunder method what will happen here is data class will do the exact same thing it did before implement the anit the repper and the equal method and then it will call this post anit Now by default it's going to call it without any parameters and then we have the ability to call the Base Class Dunder method or the Base Class initialization which is what we're doing now at this point we know that any of our Fields will have already been defined so it's fine to actually use them here when we call for example the rectangle base class now this is an example that's provided directly from the python documentation but it gives you a good kind of sense of how this works so we do need to manually call this when we're inheriting from a non dat class base class so here's another example where we inherit from another data class now when we do that things change slightly and what ends up happening is we'll actually write an initialization for this child class right here which contains the attributes which we inherited from the base class so in this case we've inherited the width and the length and then we have color now what that means is that in our Constructor we're going to actually take the width the length and then the color and the reason that's the case is because we actually look up all of these different fields using something known as reverse method resolution order now I don't want to get into that too much in this video but pretty much what it means is we start at the very very Base Class so whatever the top of the chain is so if something was uh being inherited from this one we'd start at that but in this case we start at rectangle and then we go to the child class colored rectangle which means we have the width the length and the color and you can see that this is the correct initialization now the same thing is going to happen for other methods so for equal repper Etc we're going to use the attributes or the fields in that order again starting with the base class and then going into the child class now in this case there's no need to write that post init the reason we don't need to write the post init is because the init is automatically going to have have these attributes or Fields already because of how it's inherited so now we move on to the last example which is the most advanced and this is where we need an initialization variable so let's say that we're actually writing a class and there's a value we need to accept during initialization but it's not a field that we want to be included in the class or something that's going to be used Beyond just the initialization now this is a good example where what we actually need to do is accept a database during initialization and then we look something up in that database but we don't need to store that afterwards or we don't care about the value after right we don't want this to be included in say the repper or in the equal method or anything else it's going to be generated by the data class other than the initialization now there's other ways to do this but what we can do is we can specify this as an AIT bar which is what we've imported here from data class and now what it means is that it will be included in the constructure but it won't be included in those other methods it also means that it's going to be passed automatically as a parameter to our post AIT method so we can use it for doing any custom logic or lookups that we need so in this case you see that post and nit will accept this the reason it accepts it is because it's defined as an initialization variable which tells data class to automatically pass it when it calls the post AIT method then in here what we can do is we can make sure that J is none and database is not none and if that's the case we can then assign self. J which is a field that we want to store persistently on this class with the database. lookup of J which in this case would give us value or whatever the lookup function would do this is just kind of a mock example right here anyways that is something I wanted to show you because it can get kind of advanced and just the point is that pretty much any scenario you've thought of has actually been handled by python there is a ton of documentation that you can read I will link this page in the description so with that said guys that's going to wrap up this video that has covered all of the important parts of this documentation if you found this helpful go ahead and leave a like subscribe to the channel and I will see you in another [Music] one
Info
Channel: Tech With Tim
Views: 72,840
Rating: undefined out of 5
Keywords: tech with tim, Python data classes, Tech with Tim, advanced Python, Python programming, data class tutorial, Python 3.7 features, object-oriented programming, Python coding, Python best practices, Python classes and objects, coding tutorials, Python development, learn Python, software engineering, Python tips and tricks, data structures in Python, Python for beginners, professional Python programming, Python tutorial for professionals, using data classes in Python
Id: 5mMpM8zK4pY
Channel Id: undefined
Length: 16min 11sec (971 seconds)
Published: Wed Mar 13 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.