Expert Python Tutorial #2 - Dunder_Magic Methods & The Python Data Model
"WEBVTTKind: captionsLanguage: enhello everybody and welcome to video 2 any Python expert tutorial series in this video what we're gonna be doing is talking about dunder / magic methods and B Python data model now this is very important this is something that I guarantee you've seen before but you probably just haven't understood what it actually was or why it was working the way that it did and this is actually gonna give you a great insight into the way that a lot of things in Python actually operate because until you see this you kind of just take them for granted so what I want to do is give you a very basic example of two objects in Python just kind of being used and interacting together I'm going to show you how we can create the same thing with our own Python objects and even modify existing Python objects to implement implementations or operations that we want so what I'm gonna do to start is I'm gonna just make two variables here I'm just gonna make a list and say one two three and I'll make another list that just says you know four five like that now we know that with lists we can add them together by using the plus sign right we know that that's fine that we're allowed to do that so let's actually have a look at how that looks we get that list and it adds them together now why does that work we don't really know we kind of just assumed that that's a feature in Python that we can add lists together right and that's totally fine for our intermediate kind of understanding so what about lengths right I can get the length of a list that works fine too so if I look here I got a length of three and there's all kinds of things that I can do on a list like I can index something on a list I can put you know x1 and that gives me some value here and you're like well why are you showing me all this stuff because you're going to see that this kind of syntax that we're using right here on this object because this list is actually an object that I'll prove it to you just by printing the type of it and telling you that is actually a part of a class you can see class list is implemented under the hood now you might not understand what I mean by that right now but I'm actually going to import inspect and show you and then we'll get into a little bit deeper of this understanding so what I'm gonna do is actually just say print inspect dog get source of list now list this is gonna be ridiculous when we look at this in the terminal list is a built in class oh it won't let me look at the source of the building class okay that's fine we don't need to look for now but anyways the whole point of this is that these objects here this is an object this list is they're both objects we take for granted the fact that we can perform certain operations on these objects using some special Python syntax right like even being able to multiply lists together like I can do X multiplies by 3 right that's kind of a special syntax why is it that we're able to do that well that's because this operation is implemented on the list object itself and it tells the list object how to behave such that it sees a multiplication sign right after it or such that it sees a plus sign or it sees this index or it sees a call we implement that functionality and because we can do that we can implement that on our own objects now let's do one more example so obviously we saw when we printed out the value of this right we printed out X we just printed like it just looked exactly like this it printed one two three right are in fact actually let me show you if I do a space here and I just print X let's have a look at what we get here we can see that this gets uniformly spaced even though there wasn't a space here so it's not the fact that it's just printing out exactly what this looks like there is something under the hood that's telling Python what this list object looks like and what to print when we decide to print it out so let's create our own object now actually so I'm just gonna say class person like this and let's just define in a knit method now this is actually a double underscore method or a dunder anthat or magic method whatever you'd like to call it we'll talk about how this one works in a little bit although I'm sure you guys understand so we'll just make our object person I'm gonna say pikas person like this make an instance give it a name of say Tim and then if we print the value of P well if we were you know if we looked at the list before and we saw that the list printed one two three four just printed exactly what it looked like we would assume that when we print P it should just print person Tim right it should print this well when we look at it it doesn't do that and I'm sure you've seen this before it prints the memory address location now the reason it does that is because we have not told person what to do when we try to print it it does not know what that what we should show so by default it shows the information that it thinks would be valuable which is simply just its memory address location right that's it's like representation internally in the Python program so how can we change this well we can implement what we call a dunder method or magic method which is called wrapper now I'm sure you've seen this before but essentially what wrapper does is allows us to define the string representation of an object from inside of it so what I'm gonna do is make an app string and I'm simply going to say person and then Inc here self dot name so now when we decide to print this out what we get is person Tim and I'll just do it one more time instead of getting that crappy you know just gibberish of memory address location so this is the first thing that we can do is we can implement methods such as this on our own objects to implement some kind of functionality now let's show a few others and why this is so powerful so there's actually a whole list of what we call dunder methods and this is what's part of the Python data model and some people call these just data model methods and essentially you guys can read through this if you want I'll leave the link in the description someone remind me if I forget if we scroll down to the bottom here we'll start to see that there's all kinds of these double underscore methods that we can actually implement on our own objects and obviously I'm not going to go through all of them because there's just so many to kind of talk about but let's keep going down here so for example new an it del wrapper right we have this one here string bytes format ltle eqn eg tge we'll talk about what all those are hash bool right get attribute set attribute dirt devil attribute multiplication there's all these kind of things that we can do so what I'm gonna do is actually do a weird one and I'm gonna implement the multiplication double underscore method so what this tells Python to do actually is what happens when we use a multiplication operation on objects of this type on objects of type person so what I'm actually going to do in mul here I'm going to assume actually X is going to be some integer and what I'm going to do is just take the person's name and multiply it by whatever the integer is and that's the operation we'll implement when we use the star or the asterisks on the person object so what I mean by this is I'm just simply going to say self dot name equals self dot named times X and I'll even do a little let just on thing up here I'll say if type X is not int then we'll simply just throw an exception so we'll say raise exception we'll just say invalid argument must be int or in yeah whatever does really matter we put there but that's fun okay so we'll say P equals person now what I'm gonna do is simply print P I won't print that actually will just say P times four and then we'll print P and let's have a look at what this gives us okay person Tim Tim Tim Tim Tim right so we can actually implement whatever functionality we want using this upper level Python syntax by implementing some kind of lower level dunder method that's what the whole point of this video was to do was to show you that everything that we use in Python all of these different symbols can be implemented on a lower level on our own objects and these again are like data model methods right so we can create objects such that we can add them we can multiply them we can have representations we can do a call on them we do all kinds of crazy things for example let's do define on your screen just for call let's just do self let's take some argument why not why and let's just print this value so what I'm going to do is now instead of printing p.m. I'm just gonna do P and put value 4 in there and now let's watch what happens so if I go like this we get the value for printing out you can even change this called this function right 4 so what happens is we can implement the fact that these two brackets what these two brackets do if they are on an object which is really cool it allows us to make objects that are much more usable much more readable and just almost seem like they fit in with the standard Python documentation because I don't need to necessarily call a method I could actually just put the brackets now anything you can think of with this kind of syntax you can probably implement for example define underscore underscore Len underscore on your square self return the Yulin of self thought name maybe that's how long a person is unless you can for their height or something like that then what we could do is print the land of P right so we go like this we get three as that's the name so that's kind of the idea behind these dunder methods and these data model methods the whole point is everything that's above even something like division you know greater than or equal to less than whatever it is equals index all of these things can be implemented and if you want to see the implementation details of how all these work then you can read through this data model documentation because there is a ton of them the whole point is you don't need to memorize these you just need to know that they exist and then you can think about for example if I have a class and I want to implement some kind of functionality maybe I have a polynomial class I want to add them or multiply them together then rather than having to make my own method called dot multiply what I can do is simply implement the mul double underscore method and then that will allow me to use a star on it now notice you're gonna want to make these type safe because obviously I multiplied by an integer but you could technically multiply two people together you can do all kinds of things such as that okay so now I'm just gonna show you something interesting this is just maybe to kind of enlighten you better to show you something that we could actually do in theory so what I'm gonna do is import actually miss a from Q import Q and import inspect now what I'm gonna do is just make a Q object so it's gonna say Q equals Q you don't know Q it's just a built-in data structure in Python works as a cube pretty straightforward and cryptic you okay so I just want to print queue to just show you that Q does not actually implement a wrapper method so let's just do this and you can see that we're getting some random you know kind of memory address printing up to the screen so if I wanted to actually see why this wasn't giving me that representation I could have a look into Q itself so I'd say print inspect dot get source like that and then I could print my just view object like this or not Q objects are in queue class have a look at the source code and we'll see that if we scroll through it here we don't have any dunder methods that are implementing any functionality so let's say you want to make your own queue that worked very similar to the Python queue class but you want to do things like allow the plus sign or you wanted to do things like allow the minus sign well what you could do is you say from queue import queue as q like that then you could say you were on class class queue is extends from Q and then you can implement your own done your methods so that you could override this so for example define underscore underscore wrapper like this and then what I want to do is maybe I want to show a queue but I want to say how many elements are in the cute well then in that case what I would do is return queue and then I would say queue and then I guess in this case can be self dot underscore queue length the queue size something like that now now what I do if I create a queue I say you know Q U equals Q like so and I decide to print out Q you like that so let's have a look and we can see we get cute with your items now the reason I knew to use queue size is because I read through the source code and I saw that queue size returns the length of self dog queue and I see here we have self dot Q equals DQ what else do we have all these other things so this queue actually just implements a DQ object where's the Annette it's right here it can read through you can understand how this works so if you wanted to actually add something to the queue right using maybe the plus sign and you didn't want to implement something else then what I could do is say define underscore and squared add underscore underscore self item like that and then what I would simply do here is okay let's add that to the cube so we'll say self dot put and then item so now if I want to add something like u8 instead qu + 9 and it doesn't even need to be equals I can literally just do plus 9 and if we come here and we run this now we have an object cute with length one right and I could keep doing this like a new qu plus 7 right like that and then if I wanted to I could literally implement a negative sign so I can say qu - we have to put something here but if I want and I'd say define I'm just garnish per sub underscore underscore self item and then all I can do is say so let's just say self dot get like that and that's all we need to do so now if we run this we should see Q as length one and even though I mean I don't like I just put a minus sign like that's actually I'm curious if this will even work Q mine's invalid syntax so I can do like Q - none if I wanted to and then that still will remove that item for me so this is the idea right these and under methods allow you to implement these kind of syntax things as higher-level syntax and this is what's called again the data model in Python this is how all these different objects work and these dunder methods can be very useful there's a lot of different ones I'm not gonna go through all of them but the whole point is that you understand that each one of these kind of unique pieces of syntax and the higher-level of Python maps to a lower-level dunder method that implements that implements that operation right so that's the way that this works so yeah so hopefully that kind of cleared things up on dunder methods and magic methods they're really not that complicated they're very useful and when you're creating classes where these operations make a lot of sense to do like adding subtracting multiplying especially working with numeric values being able to avoid having to create your own methods like define add X Y and being able to just implement the dunder method add and use the plus sign can make things a lot more intuitive and just easier to read in your programs so noise that has been it I hope you guys enjoyed this video on dunder math it's magic methods and the Python data model as always if there's anything you'd like to see in the future videos please do leave a comment down below like subscribe and I will see you in the next videohello everybody and welcome to video 2 any Python expert tutorial series in this video what we're gonna be doing is talking about dunder / magic methods and B Python data model now this is very important this is something that I guarantee you've seen before but you probably just haven't understood what it actually was or why it was working the way that it did and this is actually gonna give you a great insight into the way that a lot of things in Python actually operate because until you see this you kind of just take them for granted so what I want to do is give you a very basic example of two objects in Python just kind of being used and interacting together I'm going to show you how we can create the same thing with our own Python objects and even modify existing Python objects to implement implementations or operations that we want so what I'm gonna do to start is I'm gonna just make two variables here I'm just gonna make a list and say one two three and I'll make another list that just says you know four five like that now we know that with lists we can add them together by using the plus sign right we know that that's fine that we're allowed to do that so let's actually have a look at how that looks we get that list and it adds them together now why does that work we don't really know we kind of just assumed that that's a feature in Python that we can add lists together right and that's totally fine for our intermediate kind of understanding so what about lengths right I can get the length of a list that works fine too so if I look here I got a length of three and there's all kinds of things that I can do on a list like I can index something on a list I can put you know x1 and that gives me some value here and you're like well why are you showing me all this stuff because you're going to see that this kind of syntax that we're using right here on this object because this list is actually an object that I'll prove it to you just by printing the type of it and telling you that is actually a part of a class you can see class list is implemented under the hood now you might not understand what I mean by that right now but I'm actually going to import inspect and show you and then we'll get into a little bit deeper of this understanding so what I'm gonna do is actually just say print inspect dog get source of list now list this is gonna be ridiculous when we look at this in the terminal list is a built in class oh it won't let me look at the source of the building class okay that's fine we don't need to look for now but anyways the whole point of this is that these objects here this is an object this list is they're both objects we take for granted the fact that we can perform certain operations on these objects using some special Python syntax right like even being able to multiply lists together like I can do X multiplies by 3 right that's kind of a special syntax why is it that we're able to do that well that's because this operation is implemented on the list object itself and it tells the list object how to behave such that it sees a multiplication sign right after it or such that it sees a plus sign or it sees this index or it sees a call we implement that functionality and because we can do that we can implement that on our own objects now let's do one more example so obviously we saw when we printed out the value of this right we printed out X we just printed like it just looked exactly like this it printed one two three right are in fact actually let me show you if I do a space here and I just print X let's have a look at what we get here we can see that this gets uniformly spaced even though there wasn't a space here so it's not the fact that it's just printing out exactly what this looks like there is something under the hood that's telling Python what this list object looks like and what to print when we decide to print it out so let's create our own object now actually so I'm just gonna say class person like this and let's just define in a knit method now this is actually a double underscore method or a dunder anthat or magic method whatever you'd like to call it we'll talk about how this one works in a little bit although I'm sure you guys understand so we'll just make our object person I'm gonna say pikas person like this make an instance give it a name of say Tim and then if we print the value of P well if we were you know if we looked at the list before and we saw that the list printed one two three four just printed exactly what it looked like we would assume that when we print P it should just print person Tim right it should print this well when we look at it it doesn't do that and I'm sure you've seen this before it prints the memory address location now the reason it does that is because we have not told person what to do when we try to print it it does not know what that what we should show so by default it shows the information that it thinks would be valuable which is simply just its memory address location right that's it's like representation internally in the Python program so how can we change this well we can implement what we call a dunder method or magic method which is called wrapper now I'm sure you've seen this before but essentially what wrapper does is allows us to define the string representation of an object from inside of it so what I'm gonna do is make an app string and I'm simply going to say person and then Inc here self dot name so now when we decide to print this out what we get is person Tim and I'll just do it one more time instead of getting that crappy you know just gibberish of memory address location so this is the first thing that we can do is we can implement methods such as this on our own objects to implement some kind of functionality now let's show a few others and why this is so powerful so there's actually a whole list of what we call dunder methods and this is what's part of the Python data model and some people call these just data model methods and essentially you guys can read through this if you want I'll leave the link in the description someone remind me if I forget if we scroll down to the bottom here we'll start to see that there's all kinds of these double underscore methods that we can actually implement on our own objects and obviously I'm not going to go through all of them because there's just so many to kind of talk about but let's keep going down here so for example new an it del wrapper right we have this one here string bytes format ltle eqn eg tge we'll talk about what all those are hash bool right get attribute set attribute dirt devil attribute multiplication there's all these kind of things that we can do so what I'm gonna do is actually do a weird one and I'm gonna implement the multiplication double underscore method so what this tells Python to do actually is what happens when we use a multiplication operation on objects of this type on objects of type person so what I'm actually going to do in mul here I'm going to assume actually X is going to be some integer and what I'm going to do is just take the person's name and multiply it by whatever the integer is and that's the operation we'll implement when we use the star or the asterisks on the person object so what I mean by this is I'm just simply going to say self dot name equals self dot named times X and I'll even do a little let just on thing up here I'll say if type X is not int then we'll simply just throw an exception so we'll say raise exception we'll just say invalid argument must be int or in yeah whatever does really matter we put there but that's fun okay so we'll say P equals person now what I'm gonna do is simply print P I won't print that actually will just say P times four and then we'll print P and let's have a look at what this gives us okay person Tim Tim Tim Tim Tim right so we can actually implement whatever functionality we want using this upper level Python syntax by implementing some kind of lower level dunder method that's what the whole point of this video was to do was to show you that everything that we use in Python all of these different symbols can be implemented on a lower level on our own objects and these again are like data model methods right so we can create objects such that we can add them we can multiply them we can have representations we can do a call on them we do all kinds of crazy things for example let's do define on your screen just for call let's just do self let's take some argument why not why and let's just print this value so what I'm going to do is now instead of printing p.m. I'm just gonna do P and put value 4 in there and now let's watch what happens so if I go like this we get the value for printing out you can even change this called this function right 4 so what happens is we can implement the fact that these two brackets what these two brackets do if they are on an object which is really cool it allows us to make objects that are much more usable much more readable and just almost seem like they fit in with the standard Python documentation because I don't need to necessarily call a method I could actually just put the brackets now anything you can think of with this kind of syntax you can probably implement for example define underscore underscore Len underscore on your square self return the Yulin of self thought name maybe that's how long a person is unless you can for their height or something like that then what we could do is print the land of P right so we go like this we get three as that's the name so that's kind of the idea behind these dunder methods and these data model methods the whole point is everything that's above even something like division you know greater than or equal to less than whatever it is equals index all of these things can be implemented and if you want to see the implementation details of how all these work then you can read through this data model documentation because there is a ton of them the whole point is you don't need to memorize these you just need to know that they exist and then you can think about for example if I have a class and I want to implement some kind of functionality maybe I have a polynomial class I want to add them or multiply them together then rather than having to make my own method called dot multiply what I can do is simply implement the mul double underscore method and then that will allow me to use a star on it now notice you're gonna want to make these type safe because obviously I multiplied by an integer but you could technically multiply two people together you can do all kinds of things such as that okay so now I'm just gonna show you something interesting this is just maybe to kind of enlighten you better to show you something that we could actually do in theory so what I'm gonna do is import actually miss a from Q import Q and import inspect now what I'm gonna do is just make a Q object so it's gonna say Q equals Q you don't know Q it's just a built-in data structure in Python works as a cube pretty straightforward and cryptic you okay so I just want to print queue to just show you that Q does not actually implement a wrapper method so let's just do this and you can see that we're getting some random you know kind of memory address printing up to the screen so if I wanted to actually see why this wasn't giving me that representation I could have a look into Q itself so I'd say print inspect dot get source like that and then I could print my just view object like this or not Q objects are in queue class have a look at the source code and we'll see that if we scroll through it here we don't have any dunder methods that are implementing any functionality so let's say you want to make your own queue that worked very similar to the Python queue class but you want to do things like allow the plus sign or you wanted to do things like allow the minus sign well what you could do is you say from queue import queue as q like that then you could say you were on class class queue is extends from Q and then you can implement your own done your methods so that you could override this so for example define underscore underscore wrapper like this and then what I want to do is maybe I want to show a queue but I want to say how many elements are in the cute well then in that case what I would do is return queue and then I would say queue and then I guess in this case can be self dot underscore queue length the queue size something like that now now what I do if I create a queue I say you know Q U equals Q like so and I decide to print out Q you like that so let's have a look and we can see we get cute with your items now the reason I knew to use queue size is because I read through the source code and I saw that queue size returns the length of self dog queue and I see here we have self dot Q equals DQ what else do we have all these other things so this queue actually just implements a DQ object where's the Annette it's right here it can read through you can understand how this works so if you wanted to actually add something to the queue right using maybe the plus sign and you didn't want to implement something else then what I could do is say define underscore and squared add underscore underscore self item like that and then what I would simply do here is okay let's add that to the cube so we'll say self dot put and then item so now if I want to add something like u8 instead qu + 9 and it doesn't even need to be equals I can literally just do plus 9 and if we come here and we run this now we have an object cute with length one right and I could keep doing this like a new qu plus 7 right like that and then if I wanted to I could literally implement a negative sign so I can say qu - we have to put something here but if I want and I'd say define I'm just garnish per sub underscore underscore self item and then all I can do is say so let's just say self dot get like that and that's all we need to do so now if we run this we should see Q as length one and even though I mean I don't like I just put a minus sign like that's actually I'm curious if this will even work Q mine's invalid syntax so I can do like Q - none if I wanted to and then that still will remove that item for me so this is the idea right these and under methods allow you to implement these kind of syntax things as higher-level syntax and this is what's called again the data model in Python this is how all these different objects work and these dunder methods can be very useful there's a lot of different ones I'm not gonna go through all of them but the whole point is that you understand that each one of these kind of unique pieces of syntax and the higher-level of Python maps to a lower-level dunder method that implements that implements that operation right so that's the way that this works so yeah so hopefully that kind of cleared things up on dunder methods and magic methods they're really not that complicated they're very useful and when you're creating classes where these operations make a lot of sense to do like adding subtracting multiplying especially working with numeric values being able to avoid having to create your own methods like define add X Y and being able to just implement the dunder method add and use the plus sign can make things a lot more intuitive and just easier to read in your programs so noise that has been it I hope you guys enjoyed this video on dunder math it's magic methods and the Python data model as always if there's anything you'd like to see in the future videos please do leave a comment down below like subscribe and I will see you in the next video\n"