1
1

00:00:01,970  -->  00:00:03,550
<v Instructor>Hi guys, welcome back.</v>
2

2

00:00:03,550  -->  00:00:06,060
In this video we're going to be adding dataclasses
3

3

00:00:06,060  -->  00:00:07,570
to our project.
4

4

00:00:07,570  -->  00:00:10,130
So we're back with a pricing service project
5

5

00:00:10,130  -->  00:00:13,105
and at the alert model.
6

6

00:00:13,105  -->  00:00:15,420
And we're gonna be taking this init method
7

7

00:00:15,420  -->  00:00:19,077
and turning it into its dataclass equivalent.
8

8

00:00:19,077  -->  00:00:20,430
And remember what that's gonna do,
9

9

00:00:20,430  -->  00:00:22,990
it is going to allow us to compare alerts
10

10

00:00:22,990  -->  00:00:25,210
and also represent them as strings
11

11

00:00:25,210  -->  00:00:28,140
when we print them out much more effectively.
12

12

00:00:28,140  -->  00:00:30,870
That's particularly helpful for when you're debugging
13

13

00:00:30,870  -->  00:00:33,600
and you can see the alert with more information
14

14

00:00:33,600  -->  00:00:35,650
without having to drill down into it.
15

15

00:00:35,650  -->  00:00:36,790
You'll know what I mean
16

16

00:00:36,790  -->  00:00:39,073
as we start debugging this project later on.
17

17

00:00:40,330  -->  00:00:43,870
For now though, we're going to go ahead and import
18

18

00:00:43,870  -->  00:00:44,793
the dataclasses.
19

19

00:00:49,110  -->  00:00:51,750
And we're gonna apply the dataclass decorator
20

20

00:00:51,750  -->  00:00:54,633
into this alert.
21

21

00:00:55,490  -->  00:00:58,750
Now at this decorator, you can pass in
22

22

00:00:58,750  -->  00:01:02,200
some configuration properties if you want as well.
23

23

00:01:02,200  -->  00:01:05,490
For example, you can say init equal false
24

24

00:01:05,490  -->  00:01:08,773
if you don't want an init method to be generated for you.
25

25

00:01:09,720  -->  00:01:11,240
And you can pass in a bunch of more things
26

26

00:01:11,240  -->  00:01:12,720
and I'm gonna link the documentation
27

27

00:01:12,720  -->  00:01:14,800
in the resources section so you can have a look
28

28

00:01:14,800  -->  00:01:17,390
at everything that you can do with dataclasses.
29

29

00:01:17,390  -->  00:01:21,763
But for now, what I'm going to do is eq equal false.
30

30

00:01:22,660  -->  00:01:25,050
And what this is gonna do is it's going to remove
31

31

00:01:25,050  -->  00:01:28,800
all equality generation from our dataclass.
32

32

00:01:28,800  -->  00:01:30,480
So what I said earlier about us being able
33

33

00:01:30,480  -->  00:01:33,190
to compare alerts with the dataclasses,
34

34

00:01:33,190  -->  00:01:35,430
we're gonna take that away from the dataclass.
35

35

00:01:35,430  -->  00:01:38,190
So now we will no longer be able to compare alerts.
36

36

00:01:38,190  -->  00:01:40,030
Why are doing that?
37

37

00:01:40,030  -->  00:01:42,370
Well, it doesn't really make sense for us
38

38

00:01:42,370  -->  00:01:45,420
to compare two alerts in our application.
39

39

00:01:45,420  -->  00:01:49,500
So in order to prevent us from accidentally doing that
40

40

00:01:49,500  -->  00:01:53,040
we take that away and those methods won't be generated
41

41

00:01:53,040  -->  00:01:55,110
and instead when we try to compare two alerts,
42

42

00:01:55,110  -->  00:01:56,540
we'll get an error saying,
43

43

00:01:56,540  -->  00:01:58,060
these two objects are not comparable
44

44

00:01:58,060  -->  00:02:00,520
because you don't have a way of comparing them.
45

45

00:02:00,520  -->  00:02:02,320
So that's why I'm making that false.
46

46

00:02:03,450  -->  00:02:06,380
Next thing is, we're gonna take this collection string
47

47

00:02:06,380  -->  00:02:08,990
and we're gonna turn it into a dataclass.
48

48

00:02:08,990  -->  00:02:11,070
The way we do that is we first of all have to say
49

49

00:02:11,070  -->  00:02:12,580
what type it is, it's a string,
50

50

00:02:12,580  -->  00:02:14,440
and then we're gonna say it's a field,
51

51

00:02:14,440  -->  00:02:17,290
it's not going to be included in the init method
52

52

00:02:17,290  -->  00:02:19,453
and the default is going to be alerts.
53

53

00:02:20,490  -->  00:02:22,060
So what does this do,
54

54

00:02:22,060  -->  00:02:25,360
well it tells a dataclass about this collection
55

55

00:02:25,360  -->  00:02:29,240
because it is now defined in the proper dataclass format
56

56

00:02:29,240  -->  00:02:31,460
and we've got it as a field.
57

57

00:02:31,460  -->  00:02:33,530
It's not going to be included in the init method
58

58

00:02:33,530  -->  00:02:35,310
which means it cannot be modified
59

59

00:02:35,310  -->  00:02:37,430
when we create a new object
60

60

00:02:37,430  -->  00:02:39,420
and the default is going to be alerts
61

61

00:02:39,420  -->  00:02:41,230
and because it can't be modified
62

62

00:02:41,230  -->  00:02:43,173
that is gonna be the value it has.
63

63

00:02:44,570  -->  00:02:47,333
So we can now take it away from there.
64

64

00:02:49,770  -->  00:02:54,290
Next we've got item id, price limit and underscore id.
65

65

00:02:54,290  -->  00:02:57,510
So, item id is just a string
66

66

00:02:57,510  -->  00:02:59,590
and it's passed into the init method you know
67

67

00:02:59,590  -->  00:03:01,830
and that's fine.
68

68

00:03:01,830  -->  00:03:06,510
Then we've got price limit which is here a float,
69

69

00:03:06,510  -->  00:03:09,343
so we're gonna have to say that it's gonna be a float.
70

70

00:03:10,410  -->  00:03:12,270
And then we've got underscore id
71

71

00:03:12,270  -->  00:03:15,203
which is gonna be a string.
72

72

00:03:17,140  -->  00:03:18,860
And once again it's gonna be field
73

73

00:03:18,860  -->  00:03:20,310
and it's gonna have a default factory
74

74

00:03:20,310  -->  00:03:24,253
of lambda uuid uuid4 hex, as we've seen before.
75

75

00:03:25,090  -->  00:03:28,320
So that takes care of this item id,
76

76

00:03:28,320  -->  00:03:31,560
this price limit and this underscore id.
77

77

00:03:31,560  -->  00:03:33,830
What else do we have to do?
78

78

00:03:33,830  -->  00:03:36,030
Do we have to tell the dataclass anything
79

79

00:03:36,030  -->  00:03:38,660
about the superclass?
80

80

00:03:38,660  -->  00:03:42,630
Should the superclass also be a dataclass?
81

81

00:03:42,630  -->  00:03:44,530
And the answer is no to both of those.
82

82

00:03:45,460  -->  00:03:47,340
If there is a superclass,
83

83

00:03:47,340  -->  00:03:49,570
the dataclass generated init method
84

84

00:03:49,570  -->  00:03:52,040
will call the init method of the superclass for you
85

85

00:03:52,040  -->  00:03:54,320
so you don't have to worry about it.
86

86

00:03:54,320  -->  00:03:58,010
And the superclasses don't have to be dataclasses.
87

87

00:03:58,010  -->  00:04:01,350
So just a normal class works fine,
88

88

00:04:01,350  -->  00:04:04,730
the dataclass is only for generating
89

89

00:04:04,730  -->  00:04:06,480
the code that it generates.
90

90

00:04:06,480  -->  00:04:10,010
Init method, repr methods, comparisons, hashing
91

91

00:04:10,010  -->  00:04:11,410
that sort of stuff.
92

92

00:04:11,410  -->  00:04:14,240
The superclass doesn't have to be a dataclass.
93

93

00:04:14,240  -->  00:04:16,420
But we do have a final thing
94

94

00:04:16,420  -->  00:04:20,100
that this dataclass does not take care of,
95

95

00:04:20,100  -->  00:04:22,763
and that is self.item.
96

96

00:04:23,810  -->  00:04:27,620
Self.item is not passed in as a parameter
97

97

00:04:27,620  -->  00:04:32,080
and it is also not generated as a standalone function.
98

98

00:04:32,080  -->  00:04:34,540
Notice that these default factories
99

99

00:04:34,540  -->  00:04:38,370
can generate a value but they cannot access
100

100

00:04:38,370  -->  00:04:41,383
other values that are passed in to the dataclass.
101

101

00:04:42,550  -->  00:04:47,320
So there is seemingly, no way for us to do this.
102

102

00:04:47,320  -->  00:04:48,930
Which is precisely why,
103

103

00:04:48,930  -->  00:04:50,410
when you're working with dataclasses,
104

104

00:04:50,410  -->  00:04:53,320
you do have an extra dunder method
105

105

00:04:53,320  -->  00:04:55,923
which is dunder post init.
106

106

00:04:57,030  -->  00:05:02,030
The post init method will run after the init method
107

107

00:05:03,440  -->  00:05:05,430
and it has access to self.
108

108

00:05:05,430  -->  00:05:09,500
So when this method runs directly after the init,
109

109

00:05:09,500  -->  00:05:13,070
you've already got these values stored in self
110

110

00:05:13,070  -->  00:05:18,070
which means you can do self.item equal item.get by id
111

111

00:05:18,160  -->  00:05:19,793
with self.item id.
112

112

00:05:21,810  -->  00:05:24,837
Now we've got this turned into a dataclass.
113

113

00:05:25,920  -->  00:05:28,000
And it works exactly the same way as we had before,
114

114

00:05:28,000  -->  00:05:29,860
no difference.
115

115

00:05:29,860  -->  00:05:32,100
Next let's move on to item.py
116

116

00:05:32,100  -->  00:05:33,950
and we're gonna do something similar.
117

117

00:05:35,000  -->  00:05:40,000
Okay, for the collection we're going to do this,
118

118

00:05:40,100  -->  00:05:44,040
as we know and then we've got URL, tag name, query
119

119

00:05:44,040  -->  00:05:45,500
and underscore id.
120

120

00:05:45,500  -->  00:05:47,980
So that's URL is just a string.
121

121

00:05:47,980  -->  00:05:50,050
Tag name is just a string.
122

122

00:05:50,050  -->  00:05:52,070
Query is a Dict.
123

123

00:05:52,070  -->  00:05:55,030
And underscore id is a string
124

124

00:05:56,240  -->  00:06:00,573
with a default factory of lambda uuid uuid4 hex.
125

125

00:06:02,070  -->  00:06:06,020
We do have to apply the dataclass decorator here
126

126

00:06:06,020  -->  00:06:08,290
and once again I'm gonna say, eq equal false
127

127

00:06:08,290  -->  00:06:11,360
so that we can't compare two items.
128

128

00:06:11,360  -->  00:06:12,480
And that's it.
129

129

00:06:12,480  -->  00:06:14,900
And we also don't need this repr method here
130

130

00:06:14,900  -->  00:06:18,210
because the dataclass is gonna generate it for us.
131

131

00:06:18,210  -->  00:06:21,320
There is one more thing which is the self.price.
132

132

00:06:21,320  -->  00:06:24,150
Self.price is set to none
133

133

00:06:24,150  -->  00:06:28,010
in this item model, in the init method.
134

134

00:06:28,010  -->  00:06:30,513
But it is not defined in our dataclass.
135

135

00:06:32,150  -->  00:06:34,910
So once again, and just for now,
136

136

00:06:34,910  -->  00:06:37,500
we're going to keep a post init here
137

137

00:06:37,500  -->  00:06:40,763
just to define the price as none.
138

138

00:06:41,980  -->  00:06:43,340
Okay?
139

139

00:06:43,340  -->  00:06:47,173
That is so that you can still access this self.price here.
140

140

00:06:48,690  -->  00:06:51,090
Now it says that the instance attribute price
141

141

00:06:51,090  -->  00:06:53,910
is defined outside the init, and it's not wrong.
142

142

00:06:53,910  -->  00:06:56,000
It is defined inside the post init
143

143

00:06:56,000  -->  00:06:57,070
but you can be sure
144

144

00:06:57,070  -->  00:06:59,780
that this going to be called directly after init.
145

145

00:06:59,780  -->  00:07:01,260
So there's nothing to worry about
146

146

00:07:01,260  -->  00:07:02,710
and soon in just a few videos,
147

147

00:07:02,710  -->  00:07:05,320
we're actually going to move it over up here.
148

148

00:07:05,320  -->  00:07:07,993
So don't worry too much about this for just now.
149

149

00:07:10,180  -->  00:07:12,030
Finally, we'll go over to store
150

150

00:07:12,030  -->  00:07:14,993
and we'll do something more or less similar.
151

151

00:07:18,850  -->  00:07:20,680
We'll start with the collection
152

152

00:07:20,680  -->  00:07:23,260
and then we've got name, URL prefix,
153

153

00:07:23,260  -->  00:07:26,057
tag name, query and underscore id.
154

154

00:07:26,057  -->  00:07:27,670
And this one's very straightforward
155

155

00:07:27,670  -->  00:07:29,080
because there's nothing else
156

156

00:07:29,080  -->  00:07:30,700
other than these name equal name,
157

157

00:07:30,700  -->  00:07:33,490
URL prefix equal URL prefix and so on.
158

158

00:07:33,490  -->  00:07:35,493
So all we have to do is say name,
159

159

00:07:36,560  -->  00:07:37,573
URL prefix,
160

160

00:07:39,090  -->  00:07:39,983
tag name,
161

161

00:07:40,830  -->  00:07:42,420
query,
162

162

00:07:42,420  -->  00:07:43,703
and underscore id.
163

163

00:07:47,930  -->  00:07:48,763
Like that.
164

164

00:07:48,763  -->  00:07:50,680
And we can take this whole thing away.
165

165

00:07:50,680  -->  00:07:52,420
That's all the changes we have to make
166

166

00:07:52,420  -->  00:07:54,400
in order to turn our code
167

167

00:07:54,400  -->  00:07:59,020
from using old style normal classes I guess,
168

168

00:07:59,020  -->  00:08:00,700
into dataclasses.
169

169

00:08:00,700  -->  00:08:03,390
Now, there is no reason why you should aim
170

170

00:08:03,390  -->  00:08:06,250
to use dataclasses everywhere.
171

171

00:08:06,250  -->  00:08:08,363
But, there are a few benefits.
172

172

00:08:09,320  -->  00:08:11,080
The code it generates,
173

173

00:08:11,080  -->  00:08:12,870
is usually going to be better than the code
174

174

00:08:12,870  -->  00:08:14,570
we would write ourselves.
175

175

00:08:14,570  -->  00:08:17,630
Just because it has been very carefully crafted
176

176

00:08:17,630  -->  00:08:19,120
so that it is efficient.
177

177

00:08:19,120  -->  00:08:21,080
So that it gives you the information you need.
178

178

00:08:21,080  -->  00:08:23,790
So that it checks for errors and things like that
179

179

00:08:23,790  -->  00:08:26,840
that you may not otherwise check for.
180

180

00:08:26,840  -->  00:08:30,430
And also there is probably the most important reason
181

181

00:08:30,430  -->  00:08:33,970
for me at least, it is a bit more readable.
182

182

00:08:33,970  -->  00:08:36,940
You define what things this object is going to have
183

183

00:08:36,940  -->  00:08:38,090
at the top of the file.
184

184

00:08:38,990  -->  00:08:42,830
And then everything is generated for you using these.
185

185

00:08:42,830  -->  00:08:44,890
There's no separate information,
186

186

00:08:44,890  -->  00:08:47,460
there's no potential chance to forget,
187

187

00:08:47,460  -->  00:08:50,210
to put something in the init method or to add a parameter
188

188

00:08:50,210  -->  00:08:51,370
or something like that.
189

189

00:08:51,370  -->  00:08:53,030
Everything's here.
190

190

00:08:53,030  -->  00:08:54,780
If it doesn't have init false,
191

191

00:08:54,780  -->  00:08:56,380
it's included in the init method
192

192

00:08:57,410  -->  00:09:01,560
and yeah, you can just see everything in the one place.
193

193

00:09:01,560  -->  00:09:03,850
The code that is generated is good,
194

194

00:09:03,850  -->  00:09:07,340
at least in my opinion, you should check this out yourself
195

195

00:09:07,340  -->  00:09:10,870
by looking at the talk that was linked in the last video.
196

196

00:09:10,870  -->  00:09:14,140
And I am happy that this is an improvement
197

197

00:09:14,140  -->  00:09:15,713
over the previous code.
198

198

00:09:16,950  -->  00:09:18,970
So, we are ready to move on.
199

199

00:09:18,970  -->  00:09:23,750
This is better code, we can continue with our application.
200

200

00:09:23,750  -->  00:09:26,450
Thanks for joining me, I'll see you in the next video.
