Attrs, Pydantic, or Python Data Classes: Which One Is The Best?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
data classes were added to python 3.7 with pep 557. I'm using them basically all of the place in my code example so you could kind of call me your data classes junkie I guess I like them a lot but there are some things that data class are just not that good at for example data validation or converting between different data types now there are some alternatives to data classes for example the pedantic package which I covered already a while ago in another video but the data classes package itself is based on another package called Etters and Etters apart from not being a real nice thing to say in dots to somebody is also much more extensive in terms of feature set than data class so we should definitely take a closer look so today I'm going to implement the same thing using data classes by Danzig and editors and then I'm going to give you an overview of the pros and cons of each of these options so you can make a better choice for your own project picking the technology you're going to use is only one aspect of starting a new project there are lots of other things to think about so if you want to learn more about how to design a piece of software from scratch I have a free guide for you you can get this at Ironwood calls design guide it contains the seven steps I take whenever I design a new piece of software and hopefully it helps you avoid some of the mistakes I made in the past so Ironwood gold slash design guide the link is also in description of this video now if you're ready let's dive in the example that I'm going to use today is one I've used sort of before it's a simple e-commerce system with orders and products the code I have here uses data classes to model this there's a product data class that you see here and we have if I scroll down on order data class there's also an enumerated value that represents the status of an order and as you can see I'm using the string enum here from Python 3 Point 11 that automatically generates strings for us depending on these values which is quite useful now the product class has name category shipping weight unit price and tax percentage by the way I could have also picked an enumerated value for a category for the time being I simply kept it as a string and with the data class you simply specify these instance variables here at the top of the class and the type hint is then going to determine the type of the instance variable order is set up in a very similar way so that's also data class it has a status it has a creation date with a default value the date of today and products in the order is a list of products that that refers back to this class and default that's the empty list you see that I use the field function here that comes from the data classes package and there we specify a default Factory as a list so that creates the empty list for us then there's a couple of convenience methods and properties like a method for adding products and as properties for computing the subtotal the tax that you paid the total price that you paid that's a subtotal plus the tax and the total shipping weight and then I have a main function where I create a couple of products banana mango and an expensive mango and then I create the order so the status is open by default and then for each product in this list I'm going to add it to the order and then I simply print out some things I compare two products using the double equals I'll talk about that in a minute and I print some prices the total order price subtotal the value in taxes and the total weight of the order you may notice that for prices I use integers that's actually quite common to do that in this case an integer represents this smallest unit possible of a currency so if this is in dollars then this would be dollar Cent so if you would have a product with a unit price of 100 that would be a product of one dollar and here you see we have the banana which cost two dollars and fifteen cents and the reason this is done is because if you use something like a float for example for currencies then you have all kinds of imprecisions when doing computations and with integers this works much better a bigger payment providers like stripe actually also rely on integers to represent monetary amounts so the first thing that's interesting is how comparisons between objects happen what you can do with the data classes indicate which instance variables should be taken into account when you compare objects and you do that VD compare argument so here in case of the product if we want to compare two products we only want to compare the name and the category and we want to ignore the other things and you do that by setting compared to True which is the default value if you don't want an instance variable like a shipping weight for example to be taken into account in the comparison you set compared to false like I've done here so when I run this code then this is what we get we see that if we compare mango and expensive mango these are not considered the same and let's see why that happens while we see that the name and the category are actually not the same because the case is different if I were to change this to lowercase mango and lowercase fruit and then we run the code again then you're going to see that the comparison is true so these are considered the same products now of course you can simply change this Behavior by changing the value of these compare arguments so for example if you do want to make a distinction between mangoes of different prices you could set this value of compared to true and then when you run the code again the comparison ends up as being false here I have more or less the same example but then built with adders there's a couple of extra things here that I'll talk about in a minute that relates to validation but if you scroll down we see that we also have a class product but here instead of a data class we're using the Define decorator that comes from authors and you can also see that in case of the product we have comparison of the name name and a category and this is one of the nice things about authors that actually comparison is a bit more extensive than with data classes so in a data class example the only thing we can do is indicate whether comparison should be done for that instance variable or not whereas in atheros we actually have control over how these things should be compared in this case we want to make sure that when we compare a name and a category that we converted to lowercase so that the case is basically ignored In the comparison and there's a couple of other things here related to validation that I'll talk about in a minute so when I do the comparison here between mango and expensive mango which has a different case then you see that it actually Compares as being the same so apart from the difference between how objects are being compared you also see that there's a lot of similarities between actors and data classes though data class use the data class decorator at the resources Define but you still Define instance variables as part of a class in the same way using the type hint and just like data classes atheros also has a field function where you supply a factory second area in which these packages differ is validation and that's where pedantic really comes into play by the way if you're enjoying this video so far don't be an editor give it a like it helps spread the word on YouTube I have yet another version of the same example here but this uses pedantic instead of authors or data classes so we have again the same order status enum I have a product that's a base model subclass that's how by densic works it uses a inheritance relationship instead of a decorators on that way it's really different from atheros and data classes but you also specify the instance variables using typins like so and same for the order you can simply specify default values like this pedantic just like authors and data class also has a field function that we can supply with a default Factory for an Mt list so that's all exactly the same now what pedantic doesn't have is an easy way to modify comparison between objects now of course you can always overwrite the equals dollar methods but that kind of defeats the purpose of using a package like data classes where you can actually customize those things so again here I have my three products banana mango and an expensive mango and we get exactly the same result as in the other examples what's nice about pedantic is that it has lots of options for validations and that goes beyond what you can do with for example authors and one of the things that it does is that it has a couple of special types that already have some of that validation included I have a couple of examples here so for example the shipping weight I use the positive float type so this uses by dentex validation to make sure that if we create a product that the shipping weight is actually positive and that it's a float and for the unit price I do the same thing so it should be a positive integer and the tax percentage should be a float and there I can use the field function to specify that this should be greater or equal to zero or less than or equal to one so it should be a percentage basically this is very intuitive for example if we have the banana product here and I change the shipping weight to let's say a negative floating point value when I try to run this code you see we get an error validation error from pedantic that shipping weight should be greater than zero this is done simply by the type hints and by the answer has lots of these helpful types to make validation easy for example they have an email validation type they have a type for validating credit card numbers they have lots of different types for validating positive and negative numbers and there's a lot more options that I'm not going to cover in this video today if you want to do validation with data classes data classes in principle doesn't really have validation built in so you kind of have to build it yourself it's what I did here in the product class for example is that you can have a post in its method where you do some validation so in this case I'm checking that unit price is positive that the shipping weight is positive and that the tax percentage is between 0 and 1 and that raises a value error and this should probably be this because 100 and zero percent is also allowed now this will do the job but obviously pedantic has a lot more options here with adders you can also do validation it's not as extensive as pedantic but you can still do it more easily than with data classes so here for example I have my product class where I have shipping weight unit price and tax percentage and with the field function you can specify a validator and in this case I'm indicating that shifting weight should be an instance of float so this is basically built into Hatters and I'm also using the positive number validator function and that's a function that I created myself so that's what you see here so this gets an instance an authors instance and an attribute string attribute and then a value that should be in this case we can use it for INS or float and then I'm simply checking the value so this is sort of how it's done in that class but at least authors has a notion of what validation is and same thing for percentage value so I'm just checking that the value is between 0 and 1 or equal to zero one and here also for unit price tax percentage I use the value dates or arguments to supply these validators as an alternative to supplying validators as arguments to the field function you can also use a decorator in atheros here's an example of what that looks like so what are some of the pros and cons of their classes versus authors versus pedantic well first let's take a look at data classes so one of the main advantages I think of data classes is that it's a standard built-in Library into python so you don't need to install any dependencies for it you can just use it right away and because it's part of the standard Library other tools and packages might have better support for it than for either authors or pedantic I mean some tools also build directly on those packages for example fast API works really well combination with pedantic and their validation system I did a video about fast API last week by the way if you want to watch that check the link at the top data classes also have some disadvantages for example the version of data classes is tied to the version of python so if you want to use a new feature in data classes where you're going to have to upgrade your python version and that might be conflicting with other libraries that you use net or not yet compatible with the new python version for example the slots option was only added in 3.10 so if you use that you need to use python 3.10 or newer another con is that data classes is sort of a lesser version of athers and why not use authors in that case since it has more features and finally because directly tied to python as part of the standard Library it means the development of data classes also goes much slower that might also be an advantage because then data class developers are going to be way more careful to make sure that everything integrates perfectly with the version of python that it's tied to now what about aters well first like data classes it supports typing it's a super set of data class so if you've used data class for a while and you want to move up your code a notch you can easily switch to authors and it's going to feel very comfortable for you also aters has lots of extra features like better support for validation and data classes it has more control over object comparison which is really nice and finally it's trusted by NASA for the Mars mission so who wouldn't want to use a package like that right some of the cons of adders well it's an external dependency so you need to install it before you can use it also there is some confusion in that there was an older version of atoms which had less logical naming for attributes and things like that but that has been changed and the name of the package that has also been changed from enter to ethers and that's why atters with the S at the end is also called the modern actors another potential cone of atoms is that you can use types to specify the instance variables but you don't have to you can also use functions such as comfloat which kind of go around the whole typing system so in that sense it's not as strict as the builds in data classes and then finally pedantic it's really a package focused on validation and it's very good at that and has lots of helpful tools and classes functions to support that if you're using other tools like Fast API pedantic integrates very nicely with that and you can use it very intuitively pedantic is also more strict than add-ons as it enforces these type hints at runtime and also those validations with them and finally if data is invalid you're going to get a useful error message some of the cons of pedantic well like atoms it's also an external dependency so you need to install it before you can use it another corner is that it's not entirely clear when validations happen importance does it only happen when an object is instantiated or does validation also run when you change an instance variable if you figured out how this works exactly let me know in the comments another thing is that as opposed to using decorators which I think is a really nice way to deal with this like authors and data class are doing but identity relies on inheritance and in some sense that doesn't really fit with favor composition over inheritance and one of the problems is that base model which is the superclass that you inherit from has already a bunch of methods and things implemented and if you accidentally override some of these methods then that might lead to unwanted behavior and finally there's a few minor things that could be improved in pedantic like for example that the string tumbler method doesn't print out the class name which would actually be useful if it did for example here if I try to print the banana that's weird printing a banana you see when I run this it only prints the instance variable names and not the actual class name and I think that would actually be helpful so here are some thoughts about when you should use which one well data classes is from the standard Library if you don't need things like Advanced comparison or validation and I think data class is perfectly fine I'm using that all the time and it works really well if you need more control of your class definitions you want to have more advanced object comparison you use some validation and you don't mind installing an external dependency then headers is a great way to go and finally if you really need extremely powerful validation features then pedantic is hard to beat it's also more strict with regards to data types which I like a lot though I do find the pity that pedantic relies on inheritance and not on decorators like authors and data classes do so if you like this comparison that gave you some food for thought about which of these packages you should use in your project now like I said even though pedantic and patterns are both more powerful than data classes data class is actually still really pretty good and I did a video a while ago about data class where I dive more into detail about what you can do with it and you can check that video out here thanks for watching take care and see you next week
Info
Channel: ArjanCodes
Views: 42,182
Rating: undefined out of 5
Keywords: data classes python, attrs dataclasses, attrs vs dataclasses vs pydantic, dataclasses vs pydantic, attrs dataclasses pydantic, data classes, python dataclasses, dataclasses python 3.7, python data classes, data classes in python 3.7, python dataclasses example, python dataclasses compare, python dataclasses tutorial, python data classes tutorial, python data classes example, python dataclass vs pydantic, pydantic vs dataclasses vs attrs, arjancodes dataclasses, attrs, pydantic
Id: zN4VCb0LbQI
Channel Id: undefined
Length: 17min 10sec (1030 seconds)
Published: Fri Feb 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.