1
00:00:00,000 --> 00:00:03,990
Object data is data that gets carried around with the object.

2
00:00:04,000 --> 00:00:07,990
And so when you have several objects, even several objects that are based on the

3
00:00:08,000 --> 00:00:10,990
same class, they can have their own set of data.

4
00:00:11,000 --> 00:00:12,990
Let's take a look at how this is done.

5
00:00:13,000 --> 00:00:16,990
And we'll make a working copy of classes.py.

6
00:00:17,000 --> 00:00:20,990
We'll call this, casses-working.py.

7
00:00:21,000 --> 00:00:23,990
I'll go ahead and open our working copy.

8
00:00:24,000 --> 00:00:27,990
We see that we have our Duck object and the donald instance of the object.

9
00:00:28,000 --> 00:00:35,990
And all of the attributes in this object are code. They are methods.

10
00:00:36,000 --> 00:00:37,990
So let's add some data to the mix.

11
00:00:38,000 --> 00:00:42,990
We'll do this by first creating a constructor by naming a method with two

12
00:00:43,000 --> 00:00:46,990
underscores and the word init and two more underscores.

13
00:00:47,000 --> 00:00:52,990
And we'll pass it a value, call it color and we'll give it a default value of white.

14
00:00:53,000 --> 00:00:57,990
It's always a good idea to give your variables default value, unless they are

15
00:00:58,000 --> 00:00:59,990
absolutely going to be required.

16
00:01:00,000 --> 00:01:03,990
And we'll save that in an object variable.

17
00:01:04,000 --> 00:01:06,990
Object Variable is carried with the object itself.

18
00:01:07,000 --> 00:01:09,990
Remember that self is a reference to the object.

19
00:01:10,000 --> 00:01:12,990
So I say self._color = color.

20
00:01:13,000 --> 00:01:18,990
Now, I named it with an underscore for a couple of reasons.

21
00:01:19,000 --> 00:01:23,990
One reason is that I want to tell myself this is an attribute that I'm using

22
00:01:24,000 --> 00:01:26,990
locally, that I'm not going to be using directly.

23
00:01:27,000 --> 00:01:31,990
In other words, I'm not going to be accessing this variable from outside of the object.

24
00:01:32,000 --> 00:01:34,990
All of the access is going to be done from methods within the object.

25
00:01:35,000 --> 00:01:39,990
And for the most part, unless there's a really overriding reason to access

26
00:01:40,000 --> 00:01:44,990
data outside of the object without a method, then it's a really good idea to

27
00:01:45,000 --> 00:01:45,990
only do it with a method.

28
00:01:46,000 --> 00:01:46,990
Let me show you what I mean.

29
00:01:47,000 --> 00:01:59,990
It I wanted to, I could assign a value to color here. I can say donald._color = 'blue'.

30
00:02:00,000 --> 00:02:07,990
And down here, we'll just get rid of these and we'll print donald._color.

31
00:02:08,000 --> 00:02:14,990
And so, I'll save this and we'll run it and we'll see that it says blue.

32
00:02:15,000 --> 00:02:22,990
And if I print this out twice, we'll see that the first is says white, and then it says blue.

33
00:02:23,000 --> 00:02:26,990
And that's because I've gone and I've changed it here.

34
00:02:27,000 --> 00:02:32,990
And so this is what you call a side effect, and these can be very, very hard to keep track of.

35
00:02:33,000 --> 00:02:37,990
If instead, I just say I'm not going to do it that way at all.

36
00:02:38,000 --> 00:02:39,990
I'm going to do this all through Accessor Methods.

37
00:02:40,000 --> 00:02:45,990
I've a separate method for getting the color and I call this get_color and this

38
00:02:46,000 --> 00:02:49,990
will return self._color.

39
00:02:50,000 --> 00:02:54,990
And then I have another method for setting the color and I'll call this one,

40
00:02:55,000 --> 00:03:05,990
set_color, and I'll say self._color = color.

41
00:03:06,000 --> 00:03:09,990
Now, it's all controlled and I can keep track of it much easier.

42
00:03:10,000 --> 00:03:19,990
And so if I want to print donald's color, I can say print donald.get_color().

43
00:03:20,000 --> 00:03:21,990
Save that and we'll run it.

44
00:03:22,000 --> 00:03:25,990
And if I want to change his color, then I have a method that.

45
00:03:26,000 --> 00:03:34,990
donald.set_color(), and we'll say that their color is blue.

46
00:03:35,000 --> 00:03:38,990
And then we'll go ahead and print it again.

47
00:03:39,000 --> 00:03:40,990
Let's go ahead and save this and run it and see what it does.

48
00:03:41,000 --> 00:03:44,990
You might be saying to yourself, okay so what's the difference? We just made that harder.

49
00:03:45,000 --> 00:03:48,990
But did we actually make it better, and the answer is, yeah we made it better.

50
00:03:49,000 --> 00:03:53,990
The reason that it's better is that now we have code itself has control over

51
00:03:54,000 --> 00:03:55,990
what happens when that gets set.

52
00:03:56,000 --> 00:04:00,990
Let's say when I set their color that I need to save it in a database, or that

53
00:04:01,000 --> 00:04:05,990
I need to do some other things. Maybe it's not just a color, maybe it's some

54
00:04:06,000 --> 00:04:10,990
other controlling configuration thing. Maybe ducks that have blue feathers have

55
00:04:11,000 --> 00:04:11,990
to also have blue feet.

56
00:04:12,000 --> 00:04:16,990
So, when the color gets set, then I know that I've got a method that's going to

57
00:04:17,000 --> 00:04:18,990
also set the color of the feet.

58
00:04:19,000 --> 00:04:23,990
That's what going to also save it in the database or set some attribute some

59
00:04:24,000 --> 00:04:25,990
place else, based on what this change is.

60
00:04:26,000 --> 00:04:31,990
If I'm allowing it to get set just arbitrarily from outside of the object then I

61
00:04:32,000 --> 00:04:32,990
don't have that control.

62
00:04:33,000 --> 00:04:38,990
Then we might end up with the duck that's got blue feathers and green feet and

63
00:04:39,000 --> 00:04:39,990
that would never work.

64
00:04:40,000 --> 00:04:44,990
Bu enforcing this rule, and you'll notice when you read about object oriented

65
00:04:45,000 --> 00:04:49,990
code and when you learn about object oriented techniques, using these accessor

66
00:04:50,000 --> 00:04:54,990
methods is a standard and the reason for that is that it avoids side effects

67
00:04:55,000 --> 00:04:59,990
and avoids the kinds of problems that can happen when you lose control over how

68
00:05:00,000 --> 00:05:01,990
the data is being used.

69
00:05:02,000 --> 00:05:06,990
Remember one of the major advantages of object oriented programming is the encapsulation.

70
00:05:07,000 --> 00:05:10,990
And once you have that encapsulation, then that gives you control, that allows

71
00:05:11,000 --> 00:05:12,990
you to know exactly how your data is being used.

72
00:05:13,000 --> 00:05:19,990
Now the other thing that we'll notice about this is that this does not scale well.

73
00:05:20,000 --> 00:05:23,990
If I want it to be able to set say some other flags, some other values, some

74
00:05:24,000 --> 00:05:26,990
other attributes, that can quickly get out of hand.

75
00:05:27,000 --> 00:05:31,990
If they are more than two or three of these, it would become a real problem to keep track of.

76
00:05:32,000 --> 00:05:37,990
So what we tend to do in Python is to use a dictionary and to use what's

77
00:05:38,000 --> 00:05:39,990
called keyword arguments.

78
00:05:40,000 --> 00:05:43,990
If instead of just setting the color like this, I allow keyword arguments,

79
00:05:44,000 --> 00:05:58,990
kwargs like that and then based on those keyword arguments, I can set the color like this.

80
00:05:59,000 --> 00:06:03,990
That one even allows me to have a default value of white and then when I want to

81
00:06:04,000 --> 00:06:12,990
set it at the beginning, and let's just take these out here and I can say color

82
00:06:13,000 --> 00:06:15,990
equals blue, like that.

83
00:06:16,000 --> 00:06:17,990
Save that and run it and we get blue.

84
00:06:18,000 --> 00:06:25,990
And if I don't pass the argument at all, save that and run it, then we get white.

85
00:06:26,000 --> 00:06:35,990
So this scales. If I wanted to say set feet = 2, I can do that.

86
00:06:36,000 --> 00:06:36,990
Save it and run it.

87
00:06:37,000 --> 00:06:41,990
Of course, I'm not setting the color, but I'm setting another attribute.

88
00:06:42,000 --> 00:06:44,990
And if I wanted, I can have a getter for feet.

89
00:06:45,000 --> 00:06:47,990
The other side of this that doesn't scale well though is that I'm saving the

90
00:06:48,000 --> 00:06:49,990
color in a variable like this.

91
00:06:50,000 --> 00:06:53,990
Again, that could get on unwieldy and it could become difficult to keep track of.

92
00:06:54,000 --> 00:06:57,990
So, I can use a dictionary for that as well.

93
00:06:58,000 --> 00:07:04,990
In fact, I could use a dictionary for all of them and just call these variables

94
00:07:05,000 --> 00:07:09,990
and assign it to kwargs, like that.

95
00:07:10,000 --> 00:07:14,990
And for my set_color and get_color, if I wanted to have separate accessors for

96
00:07:15,000 --> 00:07:24,990
those, I could still do that. I could say variable sub color and assign that to the color.

97
00:07:25,000 --> 00:07:36,990
And I could say variables.get('color') and give it a default value and I like to

98
00:07:37,000 --> 00:07:42,990
use None in a circumstance like this and I can save that.

99
00:07:43,000 --> 00:07:47,990
And when I run it, you'll see that we get None down here.

100
00:07:48,000 --> 00:07:51,990
That just tells me that donald's color has not been set.

101
00:07:52,000 --> 00:07:54,990
But instead of this, we can make one of these that scales as well.

102
00:07:55,000 --> 00:07:57,990
Now, we're really getting into some power here.

103
00:07:58,000 --> 00:08:06,990
We can say set_variable and allow it the name. I'll call that k and then v for

104
00:08:07,000 --> 00:08:21,990
value, self.variables(), so k equals v, and get_variable(self, k).

105
00:08:22,000 --> 00:08:29,990
Return self.variables.get(k, None).

106
00:08:30,000 --> 00:08:37,990
Now instead of get_color, I can say get_variable("color").

107
00:08:38,000 --> 00:08:41,990
Save that and run it. But I've set feet. I haven't set color.

108
00:08:42,000 --> 00:08:48,990
So I can just put feet in here and then I get the number of feet.

109
00:08:49,000 --> 00:08:50,990
So, this allows us scalability.

110
00:08:51,000 --> 00:08:55,990
This allows us, if we wanted to, even after donald has been created, we could

111
00:08:56,000 --> 00:09:09,990
set his color, set_variable("color") to blue, and then down here, I can get his color as well.

112
00:09:10,000 --> 00:09:12,990
And now, we have this flexibility.

113
00:09:13,000 --> 00:09:17,990
We have a very small amount of code that can do a lot of different things.

114
00:09:18,000 --> 00:09:22,990
So, this is a technique that you'll see commonly used in Python where you are

115
00:09:23,000 --> 00:09:26,990
storing your object data in dictionary objects.

116
00:09:27,000 --> 00:09:28,990
It allows you a lot of flexibility.

117
00:09:29,000 --> 00:09:33,990
It allows you to use a lot of different data, a lot of flags, a lot of

118
00:09:34,000 --> 00:09:38,990
attributes, and to do different things with them, to save them to the databases,

119
00:09:39,000 --> 00:09:44,990
to use them as configuration options, and to vary easily be able to set them and

120
00:09:45,000 --> 00:09:46,990
get them and control them.

121
00:09:47,000 --> 00:09:48,990
So, this is one method.

122
00:09:49,000 --> 00:09:51,990
Obviously, it's not the only method and we'll see a lot of examples through out

123
00:09:52,000 --> 00:09:56,990
the rest of this course and different ways to handle object data, but this is in

124
00:09:57,000 --> 00:10:07,000
a nut shell how you use object data with objects and classes in Python.

