1
1

00:00:02,690  -->  00:00:03,840
<v ->Hey guys, welcome back.</v>
2

2

00:00:03,840  -->  00:00:08,340
In this video we're going to be talking about metaclasses.
3

3

00:00:08,340  -->  00:00:10,950
A metaclass is a concept in Python
4

4

00:00:10,950  -->  00:00:13,220
that is very frequently overlooked.
5

5

00:00:13,220  -->  00:00:16,550
And what it allows us to do is a few things.
6

6

00:00:16,550  -->  00:00:18,443
But the one we're gonna look at in this video
7

7

00:00:18,443  -->  00:00:23,443
is that it allows us to define a method inside a class
8

8

00:00:24,060  -->  00:00:27,250
that isn't defined in the class,
9

9

00:00:27,250  -->  00:00:31,050
but must be defined in a subclass.
10

10

00:00:31,050  -->  00:00:33,420
So, let's dive right into some code,
11

11

00:00:33,420  -->  00:00:34,670
and that'll be the easiest way
12

12

00:00:34,670  -->  00:00:36,370
for you to learn about this.
13

13

00:00:36,370  -->  00:00:38,610
I'm going to create a new model in here.
14

14

00:00:38,610  -->  00:00:43,333
I'm gonna call it just model.py.
15

15

00:00:44,290  -->  00:00:47,423
And here I'm gonna say, from ABC import, ABCMeta,
16

16

00:00:48,480  -->  00:00:51,240
and abstract method.
17

17

00:00:51,240  -->  00:00:52,173
There we go.
18

18

00:00:53,270  -->  00:00:55,750
And, then we're gonna define our model.
19

19

00:00:55,750  -->  00:00:59,400
And in here, we're going to inherit from ABCMeta.
20

20

00:00:59,400  -->  00:01:02,610
So, we're not going to inherit in the normal way.
21

21

00:01:02,610  -->  00:01:05,520
We're going to be using a metaclass inheritance,
22

22

00:01:05,520  -->  00:01:07,230
or a metaclass property.
23

23

00:01:07,230  -->  00:01:10,053
We're gonna say, metaclass=ABCMeta.
24

24

00:01:11,340  -->  00:01:12,930
Now, there are a couple of ways
25

25

00:01:12,930  -->  00:01:16,260
of using abstract base classes,
26

26

00:01:16,260  -->  00:01:18,280
that's what an ABC is .
27

27

00:01:18,280  -->  00:01:21,990
And this is sort of the most common way.
28

28

00:01:21,990  -->  00:01:25,180
What it means when you define a class
29

29

00:01:25,180  -->  00:01:27,737
as having an ABCMeta metaclass,
30

30

00:01:28,900  -->  00:01:31,780
is that it gives this class the ability
31

31

00:01:31,780  -->  00:01:35,100
to use abstract methods and abstract properties
32

32

00:01:35,100  -->  00:01:36,600
and things like that.
33

33

00:01:36,600  -->  00:01:39,440
What abstract means in Python,
34

34

00:01:39,440  -->  00:01:40,900
and this is what you should take away
35

35

00:01:40,900  -->  00:01:43,313
from this whole abstract class thing,
36

36

00:01:43,313  -->  00:01:48,313
what abstract means, is, this thing that we are using
37

37

00:01:49,140  -->  00:01:53,803
that is abstract, exists but isn't defined yet.
38

38

00:01:54,670  -->  00:01:57,310
So, we're going to say that all models
39

39

00:01:57,310  -->  00:02:00,710
must have a json method.
40

40

00:02:00,710  -->  00:02:02,930
And the reason we're gonna say this is because so far,
41

41

00:02:02,930  -->  00:02:06,720
our alert model has a json method,
42

42

00:02:06,720  -->  00:02:09,410
and our item model has a json method.
43

43

00:02:09,410  -->  00:02:12,850
So, all our models so far, and they will continue to do so,
44

44

00:02:12,850  -->  00:02:15,833
have a json method.
45

45

00:02:16,820  -->  00:02:18,663
So, we want to be able to say,
46

46

00:02:19,800  -->  00:02:23,765
if we have a model, it must have a json method.
47

47

00:02:23,765  -->  00:02:28,180
And the json method must be defined inside the class.
48

48

00:02:28,180  -->  00:02:30,900
And that is what an abstract class allows us to do.
49

49

00:02:30,900  -->  00:02:34,310
The way we do that is, we define the method,
50

50

00:02:34,310  -->  00:02:37,363
and we decorate it with abstract method.
51

51

00:02:38,460  -->  00:02:43,460
And inside the method, we say, raise not implemented error.
52

52

00:02:44,670  -->  00:02:45,730
Okay.
53

53

00:02:45,730  -->  00:02:50,000
So what this is saying is, we have a model class,
54

54

00:02:50,000  -->  00:02:55,000
but this model class isn't an actual thing in our programme.
55

55

00:02:55,170  -->  00:02:58,630
It is the definition of what a thing should be,
56

56

00:02:58,630  -->  00:03:00,480
or should contain.
57

57

00:03:00,480  -->  00:03:03,330
And things, or models, in our application,
58

58

00:03:03,330  -->  00:03:05,873
should contain json methods.
59

59

00:03:05,873  -->  00:03:08,130
And they are abstract methods.
60

60

00:03:08,130  -->  00:03:09,530
So what does this mean?
61

61

00:03:09,530  -->  00:03:12,640
Well, it means that now you can go into any of your models
62

62

00:03:12,640  -->  00:03:17,150
and create, you know, another model like item or alert,
63

63

00:03:17,150  -->  00:03:18,050
or whatever.
64

64

00:03:18,050  -->  00:03:23,043
And it can inherit from this model abstract class.
65

65

00:03:24,470  -->  00:03:25,303
Okay.
66

66

00:03:26,360  -->  00:03:30,010
So, if we do this, if we create a model class,
67

67

00:03:30,010  -->  00:03:32,830
such as item or alert, any of these,
68

68

00:03:32,830  -->  00:03:37,240
if we make these inherit from the model abstract class,
69

69

00:03:37,240  -->  00:03:40,600
Python will immediately tell you that your class
70

70

00:03:40,600  -->  00:03:44,130
must implement all abstract methods.
71

71

00:03:44,130  -->  00:03:45,800
So what Python is telling you is,
72

72

00:03:45,800  -->  00:03:47,780
hey you've defined this class and it inherits
73

73

00:03:47,780  -->  00:03:52,780
from this abstract class, but you have not implemented
74

74

00:03:52,940  -->  00:03:56,500
the abstract method json, which you need to implement
75

75

00:03:56,500  -->  00:03:58,343
in order for this code to be valid.
76

76

00:03:59,360  -->  00:04:01,500
Now what I'm going to do in order to show you what happens,
77

77

00:04:01,500  -->  00:04:04,640
is I'm going to right-click model.py, which is this file.
78

78

00:04:04,640  -->  00:04:07,960
I'm gonna right-click it and run it using pycharm.
79

79

00:04:07,960  -->  00:04:09,500
And then you can see nothing happens.
80

80

00:04:09,500  -->  00:04:14,500
And if I create on object of MyModel and run it again,
81

81

00:04:15,100  -->  00:04:17,390
you can see that you get an error.
82

82

00:04:17,390  -->  00:04:19,200
It says type error, can't instantiate
83

83

00:04:19,200  -->  00:04:22,053
abstract class MyModel with abstract methods json.
84

84

00:04:22,950  -->  00:04:25,120
So what is going on in the background?
85

85

00:04:25,120  -->  00:04:27,990
Why does Python accept the definition,
86

86

00:04:27,990  -->  00:04:29,400
accept it if we delete this line,
87

87

00:04:29,400  -->  00:04:32,092
but it doesn't accept it when we create it,
88

88

00:04:32,092  -->  00:04:33,600
when we're here in object?
89

89

00:04:33,600  -->  00:04:35,550
Well, what's going on behind the scenes is,
90

90

00:04:35,550  -->  00:04:39,950
Python is realising that the MyModel class
91

91

00:04:39,950  -->  00:04:43,840
does not have a method called json,
92

92

00:04:43,840  -->  00:04:46,183
that is not an abstract method.
93

93

00:04:46,183  -->  00:04:49,480
So MyModel class is inheriting from model,
94

94

00:04:49,480  -->  00:04:52,090
and that means that you're essentially copy, pasting
95

95

00:04:52,090  -->  00:04:55,710
everything inside that class, down to the child.
96

96

00:04:55,710  -->  00:04:58,650
That's essentially what inheritance means in Python.
97

97

00:04:58,650  -->  00:05:01,453
So, that means that the MyModel class
98

98

00:05:01,453  -->  00:05:04,060
also has an abstract method called json.
99

99

00:05:04,060  -->  00:05:05,630
It's essentially the same method.
100

100

00:05:05,630  -->  00:05:07,960
But it is an abstract method.
101

101

00:05:07,960  -->  00:05:12,180
And you can not instantiate, you can not create objects
102

102

00:05:12,180  -->  00:05:15,740
of classes that have abstract methods in them.
103

103

00:05:15,740  -->  00:05:20,070
Similarly, you can not create an instance of model
104

104

00:05:20,070  -->  00:05:21,010
for the same reason.
105

105

00:05:21,010  -->  00:05:23,580
You can't instantiate abstract class model
106

106

00:05:23,580  -->  00:05:25,900
with abstract methods json.
107

107

00:05:25,900  -->  00:05:27,540
So, what can you do?
108

108

00:05:27,540  -->  00:05:29,530
We're gonna go back to MyModel,
109

109

00:05:29,530  -->  00:05:31,170
and now what we're gonna say is,
110

110

00:05:31,170  -->  00:05:33,790
I'm going to implement this json method.
111

111

00:05:33,790  -->  00:05:37,310
And it's gonna return a dictionary such as,
112

112

00:05:37,310  -->  00:05:40,190
for example, name is MyModel.
113

113

00:05:42,640  -->  00:05:43,910
What does this mean now?
114

114

00:05:43,910  -->  00:05:46,370
Now it means the MyModel class
115

115

00:05:46,370  -->  00:05:49,159
no longer has an abstract method.
116

116

00:05:49,159  -->  00:05:50,290
Why?
117

117

00:05:50,290  -->  00:05:53,480
Because as soon as you try to call the json method,
118

118

00:05:53,480  -->  00:05:54,930
you can see that it doesn't have
119

119

00:05:54,930  -->  00:05:56,370
the abstract method decorator.
120

120

00:05:56,370  -->  00:05:59,660
And this is the way Python inheritance work.
121

121

00:05:59,660  -->  00:06:02,553
If we try to call model.json,
122

122

00:06:03,430  -->  00:06:05,790
what happens is, it calls the method
123

123

00:06:05,790  -->  00:06:08,660
that is defined inside the MyModel class.
124

124

00:06:08,660  -->  00:06:11,259
And if doesn't exist, then it calls the method
125

125

00:06:11,259  -->  00:06:14,250
that is defined on the parent class.
126

126

00:06:14,250  -->  00:06:16,490
And that is an abstract method.
127

127

00:06:16,490  -->  00:06:19,180
So, as soon as you define the method,
128

128

00:06:19,180  -->  00:06:21,730
not abstract, inside your MyModel class,
129

129

00:06:21,730  -->  00:06:24,900
this all works, and you get your dictionary there.
130

130

00:06:24,900  -->  00:06:29,480
So, this is a perfect way of enforcing the definition
131

131

00:06:29,480  -->  00:06:32,160
of methods in child classes.
132

132

00:06:32,160  -->  00:06:34,950
So, what we're going to do, is we're gonna leave this as is,
133

133

00:06:34,950  -->  00:06:37,570
for just a moment, and then we're gonna go
134

134

00:06:37,570  -->  00:06:39,330
over to our alert.
135

135

00:06:39,330  -->  00:06:43,770
And we're gonna say from models, model import model.
136

136

00:06:43,770  -->  00:06:47,810
And we're gonna make the alert a subclass of model.
137

137

00:06:47,810  -->  00:06:50,410
Remember, all this does in Python,
138

138

00:06:50,410  -->  00:06:53,970
is essentially access this method
139

139

00:06:53,970  -->  00:06:58,750
if the alert model does not have its own json method.
140

140

00:06:58,750  -->  00:07:01,170
The alert model does have its own json method,
141

141

00:07:01,170  -->  00:07:04,000
so whenever we access the json method of alert,
142

142

00:07:04,000  -->  00:07:07,070
we're gonna use this one, not the parent class one.
143

143

00:07:07,070  -->  00:07:10,160
But, if we define another method, sorry, another model,
144

144

00:07:10,160  -->  00:07:13,500
and we don't include the json method there,
145

145

00:07:13,500  -->  00:07:15,740
we're gonna get this warning saying,
146

146

00:07:15,740  -->  00:07:18,800
class alert, must implement all abstract methods.
147

147

00:07:18,800  -->  00:07:21,600
And we're gonna get an error if we try to do that.
148

148

00:07:21,600  -->  00:07:25,170
So, it's going to enforce this method definition.
149

149

00:07:25,170  -->  00:07:27,270
We're gonna do the same in the item model.
150

150

00:07:37,472  -->  00:07:38,420
Alright.
151

151

00:07:38,420  -->  00:07:41,340
So, now that we have this in both our models,
152

152

00:07:41,340  -->  00:07:45,380
we can go and start moving things from our models
153

153

00:07:45,380  -->  00:07:47,407
into this class.
154

154

00:07:47,407  -->  00:07:49,320
Why would you want to do that?
155

155

00:07:49,320  -->  00:07:52,810
Well, abstract classes don't mean
156

156

00:07:52,810  -->  00:07:56,730
that all the methods in them must be abstract methods.
157

157

00:07:56,730  -->  00:08:00,030
You can have methods that are not abstract methods.
158

158

00:08:00,030  -->  00:08:03,070
We're going to learn what that means in the next video.
159

159

00:08:03,070  -->  00:08:04,220
So, I'll see you there.
