Decluttering the Song Class
00:00
In this lesson, you’ll be moving on to something a bit more Pythonic, which will allow you to remove some of the clutter in the Song
class. So what I am talking about here is in line five and beyond, you can see the .__init__()
method and all the .__init__()
method does is it takes three input parameters and stores them as instance attributes of the Song
class.
00:23 So there isn’t an awful lot of logic happening in this class. Actually, there is none. There are no methods in this class, not yet. So if the purpose of a class really is to just store data, then Python allows you to create those classes as data classes, and then Python can take care of a lot of the boilerplate stuff that sits behind classes for you.
00:46
In particular, what it will mean is that you can get rid of the .__init__()
method. So how do you implement that? Well, the first step is to import the dataclasses
module.
00:57
So on line three, from dataclasses
01:02
import dataclass,
and let’s also import asdict
, which is a function that you will use a little bit later on in this lesson.
01:12
Then you would need to use the @dataclass
decorator. So just above class Song:
so on line five, type @dataclass
.
01:25
So that decorates the Song
class, and that allows you to remove the .__init__()
method. So line seven, you can remove the .__init__()
method,
01:37
and then select lines seven to nine and change the indentation. Now there is no longer an .__init__()
method, so self
no longer applies.
01:45
So on lines seven, eight, and nine, you can remove self
01:53
dot, and the input parameters that were going into the .__init__()
method are no longer applicable, so you can delete those. So from line seven, delete = song_id,
but replace that with : str
.
02:06
So for data classes, you do have to point out what the data type is. So my song_id
is going to be a string. For title
on line eight, same thing, remove = title
and type : str
, because that’s also a string.
02:20
And the same for line nine and replace with : str
. And that is it. That is now your data class. And I think you agree that looks a little bit less cluttered.
02:32
Next thing I wanted to show you is the asdict()
function of the dataclasses
module.
02:39
So if you scroll down to the JSONSerializer
product, lines 39 to 41, you can see that there is a dictionary that gets passed into the js.dumps()
functionality.
02:53
Now that dictionary needed to be created manually. So the keys are defined manually. So id
, title
, and artist
.
03:03
Now what the asdict()
function allows you to do or what it does for you, is that it creates this dictionary automatically for you. So that again will declutter the code.
03:15
So the way that works is you select the dictionary from row 39 to 41, delete that and type asdict()
. You then need to pass it a data class. Because remember asdict()
is a function of the dataclasses
module and it can only be applied to data classes.
03:33
Now the data class we’re talking about is our Song
class. Now how does the __str__()
dunder method know about the Song
class?
03:42
Well, it knows self
. So self
is an input parameter into the __str__()
dunder method. And in line 36, the self.song
instance attribute was created.
03:53
And that instance attribute captures song
, which is what was passed in through the .__init__()
method.
04:01
So a Song
data class is really self.song
because self
contains the self.song
instance attribute. So that cleans up the code a little bit.
04:14 Let’s see how it works. Save the code, and then restart your REPL.
04:21
Now the interface hasn’t changed, so from serializer import Song
and serialize()
. Create a song. So my song, I’m going to give it a different id
.
04:33
So instead of 1
, let’s make that 15
,
04:37
and then you serialize()
pass it my_song
and let’s try JSON. And that gives you the output as expected.
04:46
Or does it? Because the output has changed slightly. This used to say id
as opposed to song_id
. So where does song_id
come from?
04:58
Well, you’ve implemented the asdict()
function, which looks at the Song
data class and then uses the class’s attributes as the keys of this dictionary.
05:08
And that attribute was song_id
, not id
. So to keep this the same, you could change the data class attributes to id
as opposed to song_id
, but that might or might not be entirely what the client wants.
05:25
What I just wanted to show you is that by using the asdict()
functionality, you can save yourself some time, and have the asdict()
function read the attributes of the data class and populate the dictionary for you automatically.
05:40 And depending on your situation, that might or might not be helpful.
05:46 Now for the rest of the course, that doesn’t actually matter because in the next lesson you’ll be completely redesigning the code and this issue will go away.
05:54 What you will be looking at is how to make the products more generic.
Become a Member to join the conversation.