Easy-to-follow video tutorials help you learn software, creative, and business skills.Become a member
Object data is data that gets carried around with the object. And so when you have several objects, even several objects that are based on the same class, they can have their own set of data. Let's take a look at how this is done. And we'll make a working copy of classes.py. We'll call this, casses-working.py. I'll go ahead and open our working copy. We see that we have our Duck object and the donald instance of the object. And all of the attributes in this object are code. They are methods.
So let's add some data to the mix. We'll do this by first creating a constructor by naming a method with two underscores and the word init and two more underscores. And we'll pass it a value, call it color and we'll give it a default value of white. It's always a good idea to give your variables default value, unless they are absolutely going to be required. And we'll save that in an object variable. Object Variable is carried with the object itself.
Remember that self is a reference to the object. So I say self._color = color. Now, I named it with an underscore for a couple of reasons. One reason is that I want to tell myself this is an attribute that I'm using locally, that I'm not going to be using directly. In other words, I'm not going to be accessing this variable from outside of the object. All of the access is going to be done from methods within the object. And for the most part, unless there's a really overriding reason to access data outside of the object without a method, then it's a really good idea to only do it with a method.
Let me show you what I mean. It I wanted to, I could assign a value to color here. I can say donald._color = 'blue'. And down here, we'll just get rid of these and we'll print donald._color. And so, I'll save this and we'll run it and we'll see that it says blue. And if I print this out twice, we'll see that the first is says white, and then it says blue.
And that's because I've gone and I've changed it here. And so this is what you call a side effect, and these can be very, very hard to keep track of. If instead, I just say I'm not going to do it that way at all. I'm going to do this all through Accessor Methods. I've a separate method for getting the color and I call this get_color and this will return self._color. And then I have another method for setting the color and I'll call this one, set_color, and I'll say self._color = color.
Now, it's all controlled and I can keep track of it much easier. And so if I want to print donald's color, I can say print donald.get_color(). Save that and we'll run it. And if I want to change his color, then I have a method that. donald.set_color(), and we'll say that their color is blue. And then we'll go ahead and print it again.
Let's go ahead and save this and run it and see what it does. You might be saying to yourself, okay so what's the difference? We just made that harder. But did we actually make it better, and the answer is, yeah we made it better. The reason that it's better is that now we have code itself has control over what happens when that gets set. Let's say when I set their color that I need to save it in a database, or that I need to do some other things. Maybe it's not just a color, maybe it's some other controlling configuration thing. Maybe ducks that have blue feathers have to also have blue feet.
So, when the color gets set, then I know that I've got a method that's going to also set the color of the feet. That's what going to also save it in the database or set some attribute some place else, based on what this change is. If I'm allowing it to get set just arbitrarily from outside of the object then I don't have that control. Then we might end up with the duck that's got blue feathers and green feet and that would never work. Bu enforcing this rule, and you'll notice when you read about object oriented code and when you learn about object oriented techniques, using these accessor methods is a standard and the reason for that is that it avoids side effects and avoids the kinds of problems that can happen when you lose control over how the data is being used.
Remember one of the major advantages of object oriented programming is the encapsulation. And once you have that encapsulation, then that gives you control, that allows you to know exactly how your data is being used. Now the other thing that we'll notice about this is that this does not scale well. If I want it to be able to set say some other flags, some other values, some other attributes, that can quickly get out of hand. If they are more than two or three of these, it would become a real problem to keep track of.
So what we tend to do in Python is to use a dictionary and to use what's called keyword arguments. If instead of just setting the color like this, I allow keyword arguments, kwargs like that and then based on those keyword arguments, I can set the color like this. That one even allows me to have a default value of white and then when I want to set it at the beginning, and let's just take these out here and I can say color equals blue, like that.
Save that and run it and we get blue. And if I don't pass the argument at all, save that and run it, then we get white. So this scales. If I wanted to say set feet = 2, I can do that. Save it and run it. Of course, I'm not setting the color, but I'm setting another attribute. And if I wanted, I can have a getter for feet. The other side of this that doesn't scale well though is that I'm saving the color in a variable like this.
Again, that could get on unwieldy and it could become difficult to keep track of. So, I can use a dictionary for that as well. In fact, I could use a dictionary for all of them and just call these variables and assign it to kwargs, like that. And for my set_color and get_color, if I wanted to have separate accessors for those, I could still do that. I could say variable sub color and assign that to the color.
And I could say variables.get('color') and give it a default value and I like to use None in a circumstance like this and I can save that. And when I run it, you'll see that we get None down here. That just tells me that donald's color has not been set. But instead of this, we can make one of these that scales as well.
Now, we're really getting into some power here. We can say set_variable and allow it the name. I'll call that k and then v for value, self.variables(), so k equals v, and get_variable(self, k). Return self.variables.get(k, None). Now instead of get_color, I can say get_variable("color").
Save that and run it. But I've set feet. I haven't set color. So I can just put feet in here and then I get the number of feet. So, this allows us scalability. This allows us, if we wanted to, even after donald has been created, we could set his color, set_variable("color") to blue, and then down here, I can get his color as well.
And now, we have this flexibility. We have a very small amount of code that can do a lot of different things. So, this is a technique that you'll see commonly used in Python where you are storing your object data in dictionary objects. It allows you a lot of flexibility. It allows you to use a lot of different data, a lot of flags, a lot of attributes, and to do different things with them, to save them to the databases, to use them as configuration options, and to vary easily be able to set them and get them and control them.
So, this is one method. Obviously, it's not the only method and we'll see a lot of examples through out the rest of this course and different ways to handle object data, but this is in a nut shell how you use object data with objects and classes in Python.
Get unlimited access to all courses for just $25/month.Become a member
61 Video lessons · 104465 Viewers
56 Video lessons · 116380 Viewers
71 Video lessons · 85608 Viewers
131 Video lessons · 40973 Viewers
Access exercise files from a button right under the course name.
Search within course videos and transcripts, and jump right to the results.
Remove icons showing you already watched videos if you want to start over.
Make the video wide, narrow, full-screen, or pop the player out of the page into its own window.
Click on text in the transcript to jump to that spot in the video. As the video plays, the relevant spot in the transcript will be highlighted.