1
00:00:00,060 --> 00:00:03,480
Now that we've seen how we can create a new class.

2
00:00:03,540 --> 00:00:06,060
Even if it's a class with nothing inside.

3
00:00:06,600 --> 00:00:10,290
And we've seen how we can create a new object from that class

4
00:00:10,740 --> 00:00:14,010
by using the same code that we used in yesterday's lessons.

5
00:00:14,430 --> 00:00:19,350
The next question is: "Well, how do we create an attribute for that class?". Well,

6
00:00:19,350 --> 00:00:24,350
one of the easiest ways of doing this is simply tapping into your object and

7
00:00:24,390 --> 00:00:26,130
then adding an attribute.

8
00:00:26,310 --> 00:00:31,310
So we could say user_1.id = 

9
00:00:32,460 --> 00:00:33,293
"001".

10
00:00:33,960 --> 00:00:38,960
And we could add as many attributes as we want just by using this method of

11
00:00:39,570 --> 00:00:42,570
using the dot notation after the name of the object,

12
00:00:42,960 --> 00:00:47,370
and then just adding any piece of data we want. So now,

13
00:00:47,370 --> 00:00:51,930
if I go ahead and print user_1.username,

14
00:00:52,290 --> 00:00:55,860
you'll see that this attribute now exists in this object

15
00:00:55,880 --> 00:00:56,713
[Inaudible]

16
00:00:58,910 --> 00:01:03,470
And you can see the value that's held in that attribute being printed in the

17
00:01:03,470 --> 00:01:05,870
console. So just a quick reminder,

18
00:01:05,900 --> 00:01:10,820
an attribute is a variable that's associated with an object.

19
00:01:11,450 --> 00:01:16,130
So it's almost as if we just created a new variable, but in this case,

20
00:01:16,160 --> 00:01:20,630
we've attached it to an object. But here's a question though,

21
00:01:21,710 --> 00:01:25,640
if we had lots and lots of attributes like this,

22
00:01:25,880 --> 00:01:29,030
and every single time we create a new user,

23
00:01:29,420 --> 00:01:34,420
let's say we created user_2 and we had to do the same thing,

24
00:01:34,550 --> 00:01:36,830
create it from the class and then say,

25
00:01:36,830 --> 00:01:41,000
user_2.id = "002",

26
00:01:41,120 --> 00:01:43,910
and user_2.username

27
00:01:45,440 --> 00:01:49,430
= "jack". And this is one,

28
00:01:49,610 --> 00:01:54,500
a little bit prone to error because it's perfectly valid for me to make a typo

29
00:01:54,530 --> 00:01:58,940
or change the name of an attribute where I end up with something like this.

30
00:01:59,300 --> 00:02:02,120
So is there a way of making this simpler?

31
00:02:02,510 --> 00:02:06,770
How can I specify all these starting pieces of information

32
00:02:07,040 --> 00:02:11,300
when I create my object from the class? Now,

33
00:02:11,330 --> 00:02:15,320
in order to do this, we have to understand something called a constructor,

34
00:02:15,770 --> 00:02:20,770
which is a part of the blueprint that allows us to specify what should happen

35
00:02:21,470 --> 00:02:24,410
when our object is being constructed.

36
00:02:25,160 --> 00:02:29,240
And this is also known in programming as initializing

37
00:02:29,270 --> 00:02:32,840
an object. When the object is being initialized,

38
00:02:32,870 --> 00:02:37,870
we can set variables or counters to they're starting values. In Python,

39
00:02:39,560 --> 00:02:44,560
the way that we would create the constructor is by using a special function,

40
00:02:45,980 --> 00:02:47,570
which is the init function.

41
00:02:48,140 --> 00:02:52,070
And you can tell it's special because it isn't just the Def keyword

42
00:02:52,310 --> 00:02:55,850
and then the name of the function. It's got two underscores

43
00:02:55,910 --> 00:02:57,110
either side of the name.

44
00:02:57,740 --> 00:03:02,740
And this means that it's a method that the Python interpreter knows about and

45
00:03:03,100 --> 00:03:05,800
knows that it has a special function. Now,

46
00:03:05,800 --> 00:03:10,800
what is the special function? Well, it's normally used to initialize the attributes.

47
00:03:12,580 --> 00:03:14,260
So if inside our class

48
00:03:14,590 --> 00:03:19,590
we add this init function and you can see as soon as I write def and then 

49
00:03:19,690 --> 00:03:23,320
init, I've really got autofill helping me so I can just hit enter

50
00:03:23,620 --> 00:03:25,510
once it's selected. Now,

51
00:03:25,630 --> 00:03:30,630
inside this init function is where we initialize or create the starting

52
00:03:30,970 --> 00:03:33,940
values for our attributes. Now,

53
00:03:34,000 --> 00:03:39,000
the important thing to remember is that the init function is going to be called

54
00:03:39,370 --> 00:03:43,210
every time you create a new object from this class.

55
00:03:43,690 --> 00:03:45,400
For example, if I print,

56
00:03:47,830 --> 00:03:51,460
then every time that this construction happens

57
00:03:51,730 --> 00:03:53,770
when we create a new user,

58
00:03:54,130 --> 00:03:57,220
then this print statement is going to be triggered.

59
00:03:59,920 --> 00:04:03,940
So you can see here, this print statement gets triggered

60
00:04:04,360 --> 00:04:08,410
and then we print the user_1's username, and then we've got 

61
00:04:08,410 --> 00:04:12,490
another user being created. Just as a quick reminder,

62
00:04:12,520 --> 00:04:16,720
the attributes are the things that the object will have.

63
00:04:17,350 --> 00:04:22,210
And they are basically just variables that are associated with the final

64
00:04:22,210 --> 00:04:25,870
object. So for example, if you're constructing a car bject,

65
00:04:25,900 --> 00:04:29,500
then one of those attributes could be the number of seats it has and

66
00:04:29,500 --> 00:04:31,150
normally that's equal to five.

67
00:04:31,720 --> 00:04:36,220
So how do we set these attributes in the constructor? Well,

68
00:04:36,220 --> 00:04:37,930
this is what the code would look like.

69
00:04:38,350 --> 00:04:42,460
We have our init function and inside the init function

70
00:04:42,820 --> 00:04:44,950
in addition to this thing called self

71
00:04:45,010 --> 00:04:50,010
which is the actual object that's being created or being initialized,

72
00:04:50,890 --> 00:04:54,250
in addition, you can add as many parameters as you wish.

73
00:04:54,670 --> 00:04:59,670
And that parameter is going to be passed in when an object gets constructed from

74
00:05:00,850 --> 00:05:04,300
this class. And once you receive that data,

75
00:05:04,390 --> 00:05:09,010
then you can use it to set the object's attributes.

76
00:05:10,090 --> 00:05:14,470
This is what it would look like when we actually call our constructor.

77
00:05:15,250 --> 00:05:20,250
We know that we can create an object by calling the name of the class and then

78
00:05:20,980 --> 00:05:25,810
adding the parentheses. But if inside our init function

79
00:05:25,900 --> 00:05:27,970
we have some additional parameters,

80
00:05:28,240 --> 00:05:32,350
then we can also pass in data to those parameters

81
00:05:32,470 --> 00:05:36,460
which will be used to set the attributes for that object.

82
00:05:36,760 --> 00:05:40,330
So in this case, once this line of code has completed,

83
00:05:40,510 --> 00:05:44,710
then my_car.seats is going to be equal to five.

84
00:05:45,790 --> 00:05:49,390
And this is exactly the same as if we created our

85
00:05:49,390 --> 00:05:53,560
my_car object first and then we said my_car.seats = 5.

86
00:05:53,590 --> 00:05:55,180
It's completely the same.

87
00:05:56,230 --> 00:06:00,500
But it does make it a lot quicker when you're creating a lot of objects that

88
00:06:00,500 --> 00:06:05,150
need all the same attributes. Let's see how we would do it here.

89
00:06:05,150 --> 00:06:07,400
We've got our init function already declared.

90
00:06:08,000 --> 00:06:11,780
So if we wanted to pass over a user ID

91
00:06:11,810 --> 00:06:15,890
when we construct our objects, we can add that as a parameter

92
00:06:16,340 --> 00:06:20,060
and then inside the init we can say self.id,

93
00:06:20,330 --> 00:06:25,330
so self.id is going to be the attribute that's associated with this class

94
00:06:25,910 --> 00:06:30,910
and we can set it equal to the user_id that's passed in when any user gets

95
00:06:31,580 --> 00:06:35,450
constructed. So now when we create our user,

96
00:06:36,050 --> 00:06:40,880
instead of creating these attributes later on, at the time of construction

97
00:06:41,000 --> 00:06:44,420
you can already see that we can add a user ID.

98
00:06:45,170 --> 00:06:47,000
So let's give it the same ID.

99
00:06:48,020 --> 00:06:50,990
And now let's add another attribute.

100
00:06:51,320 --> 00:06:56,320
So we're going to pass in the username and I'm going to set the attribute

101
00:06:56,930 --> 00:07:00,710
self.username equal the username that's past it.

102
00:07:01,280 --> 00:07:05,510
Notice how in this case I've named my parameter user_id

103
00:07:05,840 --> 00:07:10,640
and that value is going to become the self.id attribute.

104
00:07:11,060 --> 00:07:14,120
So notice how these two actually have different names.

105
00:07:14,510 --> 00:07:17,480
You can name either of these anything you want.

106
00:07:18,230 --> 00:07:23,120
It's normally convention that you will see the name of the parameter be equal to

107
00:07:23,120 --> 00:07:27,590
the name of the attribute, but you don't always have to stick to these rules.

108
00:07:28,970 --> 00:07:33,590
Now let's go back to our constructor whereas previously it was empty,

109
00:07:33,830 --> 00:07:38,830
now we have our user ID being passed in and I can now pass in the second

110
00:07:39,620 --> 00:07:44,060
attribute, which is the username. So my username was going to be Angela.

111
00:07:45,650 --> 00:07:49,370
And now we've created a new user,

112
00:07:49,520 --> 00:07:53,480
which is user_1 from this user class

113
00:07:53,690 --> 00:07:58,690
and we're initializing it with these starting values where the first value is

114
00:07:59,690 --> 00:08:03,860
going to become the user ID which is going to be the self.id,

115
00:08:04,220 --> 00:08:08,780
and the second value is going to become the self.username. So now,

116
00:08:08,780 --> 00:08:12,560
if I wanted to print the user_1's username,

117
00:08:12,950 --> 00:08:14,420
then I can simply write

118
00:08:14,420 --> 00:08:17,690
user_1.username exactly the same way as before,

119
00:08:17,990 --> 00:08:21,350
or if I wanted the ID, it would be user_1.id.

120
00:08:22,070 --> 00:08:26,750
So now let's comment out the rest of the code and hit run,

121
00:08:27,680 --> 00:08:32,179
and you can see we've got the user ID being printed here. Now,

122
00:08:32,179 --> 00:08:35,539
remember that when you add parameters to the constructor

123
00:08:35,659 --> 00:08:36,919
which is the init function,

124
00:08:37,460 --> 00:08:42,460
you're now saying that whenever a new object is being constructed from this

125
00:08:43,130 --> 00:08:47,600
class, it must provide these two pieces of data.

126
00:08:48,530 --> 00:08:53,150
If we uncomment this and you try to run it, you'll see you get an error.

127
00:08:53,840 --> 00:08:56,160
And it says that on line 12,

128
00:08:56,940 --> 00:09:00,840
this user is being created from the user class.

129
00:09:01,320 --> 00:09:06,180
But according to the init, we're actually missing two required arguments;

130
00:09:06,360 --> 00:09:08,010
user ID and username.

131
00:09:08,790 --> 00:09:12,300
So now when we create any object from this class,

132
00:09:12,600 --> 00:09:16,290
we have to provide the user ID and the username.

133
00:09:17,190 --> 00:09:20,190
But this is now much more convenient, right?

134
00:09:20,250 --> 00:09:23,970
While we previously needed three lines of code, we now only have one.

135
00:09:25,200 --> 00:09:27,540
Now sometimes when we're creating our attributes,

136
00:09:27,840 --> 00:09:31,170
we might want a default value to start with.

137
00:09:31,230 --> 00:09:35,460
And if at some later point in our program we want to modify it,

138
00:09:35,460 --> 00:09:36,840
then we'll do it at that point.

139
00:09:37,140 --> 00:09:42,140
But it doesn't make sense for all attributes to be initialized when we actually

140
00:09:42,510 --> 00:09:46,200
create our object. So if, for example, in our case,

141
00:09:46,230 --> 00:09:50,010
let's say that we were coding up the Instagram app, right? Well,

142
00:09:50,010 --> 00:09:53,160
each of the Instagram users, they would have an ID,

143
00:09:53,430 --> 00:09:56,940
they would have a username and they would probably have a follower count.

144
00:09:57,330 --> 00:10:01,170
So they might have something like self.followers.

145
00:10:02,460 --> 00:10:07,050
This is always going to start out as zero, right? You start a new account,

146
00:10:07,110 --> 00:10:10,350
you're going to have zero followers. You might get some followers later on,

147
00:10:10,620 --> 00:10:11,453
you might not.

148
00:10:11,700 --> 00:10:16,700
But it doesn't make sense for followers to be something that we have to provide

149
00:10:17,520 --> 00:10:19,410
whenever we construct a new object.

150
00:10:19,680 --> 00:10:23,670
It seems very wasteful to have to always write zero

151
00:10:23,880 --> 00:10:27,900
when you construct any object from this class. So in Python,

152
00:10:27,900 --> 00:10:31,770
we can also provide a default value just as I've done here.

153
00:10:32,220 --> 00:10:37,170
Instead of setting it equal to one of the parameters that's being passed in when

154
00:10:37,170 --> 00:10:41,610
this class is being initialized, instead I'm just setting it to a value,

155
00:10:41,640 --> 00:10:46,470
which is zero. Let's get rid of that from the initializer

156
00:10:46,500 --> 00:10:48,840
because we now have a default value of zero.

157
00:10:49,380 --> 00:10:52,530
And if I go ahead and print my, let's say,

158
00:10:52,530 --> 00:10:57,180
user_1.followers attribute, and I hit run,

159
00:10:57,570 --> 00:11:02,570
then you can see it's zero because all objects being created from this class will

160
00:11:04,170 --> 00:11:07,830
have a followers attribute that set out to zero to begin with.

