Keep Track of Food With Non-Public Attribute
00:00
Next, I want to make it possible for these animals to eat something. When I drafted out this method signature here, just real quick, I said def eat()
, and then in parentheses, self
and food
, so considering that maybe I want to be able to pass in a food item just like we did with the sound in the .talk()
method earlier.
00:20 But now I’m thinking I want to kind of take this a different way. I’m not going to really let them decide what food they’re going to eat. They’re just going to get what they’re going to get.
00:29 But I want to instead do something to keep track of how much they’ve eaten and also figure out whether they’re hungry or not. Let’s start by implementing a possibility for us to keep track of how much they’ve eaten so far.
00:43
And for that, I’m going to add a new attribute to the .__init__()
method. But this attribute is not going to be something that you need to pass when you’re actually instantiating one of those animals, but instead it’s going to be a non-public attribute.
00:59
So I will say self._stuff_in_belly
, and I’ll start by setting this to 0
. Two things here.
01:11
So first of all, you can see that I’ve created this self._stuff_in_belly
, and I set it to 0
. And this is not related to any argument that you’re going to have to pass when you’re instantiating an Animal
object or instantiating any of its child classes.
01:28 But I can still set it, right. So this initializer runs every time after an object gets created. And that means that you can assign variables to the instance.
01:39
And in this case, I’m just going to assign 0
to _stuff_in_belly
every time a new animal gets instantiated. And that just says like, okay, this animal just started existing. It doesn’t have anything in its belly, right?
01:52 And to signify that I’m working with an attribute that I’m probably not going to want to show to the interface, like no one’s going to directly interact with the stuff in the belly of my animals.
02:05 So I’m using this underscore at the beginning. This is just a convention in Python to signify that something isn’t really meant to be used when you’re actually interacting.
02:15 But we’re going to use this attribute internally to decide is this animal hungry or not? Long story short, we have a new attribute on each animal, and that’s just for now set to zero.
02:29
But now inside of .eat()
, I can do something with this attribute. In my .eat()
method, I have access to the instance. So if I’m calling .eat()
, I’m going to increment ._stuff_in_belly
.
02:41
So I will say self._stuff_in_belly
,
02:48
and I will just increment it by one: += 1
, meaning just if the .eat()
method gets called, then this counter in here of how much food is inside of their belly is going to be incremented by one.
03:02 And so I’m doing this with this non-public attribute because I don’t really want anyone to see that directly. But it would still be nice to have some way to check in whether or not that animal is hungry, because we don’t want to necessarily feed it when it’s not hungry at all.
03:18 But currently we wouldn’t know at all whether or not anything happened when we’re making the animal eat. So let’s return something from that function, and I’ll just stick with what we’re doing on this farm.
03:29
We’re just going to keep returning strings to give information to what’s actually going on. So in this case, I’m also just going to say that "{self.name}
03:40
is eating"
, so I put self.name
again in the curly braces inside of the f-string, and then just continue the string by saying this animal is eating.
03:50
You can see that I’m not referencing the ._stuff_in_belly
value here in the string. And that’s just because, like I signified with this leading underscore, I want it to be non-public.
04:01 So I don’t really ever want to show to the user what the value of this is.
04:07 Let’s just quickly test out whether this is working, and then I’ll show you some more how I imagine this. Let’s start by creating a sheep.
04:19 Lizzy is my go-to name, it seems.
04:29
And then I should be able to say sheep.eat()
, without passing anything. And we can see that Lizzy is eating. And also the non-public attribute ._stuff_in_belly
should be set to 1
now. And I can always check that, right? It’s just non-public.
04:46
I’m not supposed to look at it, but I still can. So if I say sheep._stuff_in_belly
, you can see that it currently points to 1
. And if I let Lizzy
eat once more, then ._stuff_in_belly
should be set to 2
. Okay, so this is working.
05:04 Lizzy can eat, which is great, but now I want to also give some sort of an interface to the contents of the belly of the animals, basically. And I’m thinking of doing that with just like figuring out whether the animal is hungry or not, and let’s try to model something about that in the next lesson.
Become a Member to join the conversation.