Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Discover an Issue Referencing Location Objects

00:00 So you’ve finished implementing the .move() method, which makes it more than three instance methods already, but this is an interesting one because you’re interacting with other classes as well. So you’re interacting with a location object from your Animal object.

00:15 Let’s just give it a spin to see how it’s currently working out. I’m going to run this code and play around with it a bit more, and we are going to work with a dog again.

00:36 I can print a dog. The happy black dog Puppy jumps over the lazy dog. So currently, one thing that jumps to mind for me now here is that I’ve made ._location a non-public attribute, which means that the user of my Farm module basically is not really expected to do anything with ._location themselves.

01:01 But previously when I was testing, I did want to look where is the dog at at the moment, right? So it would be nice to have an actually publicly accessible location that is meant to be accessed by the user so that they can check where’s an animal at. And when I see the string, I might include it into the output here as well. Let’s try that out.

01:22 Just putting it into the .__str__() of the Animal. So I’m scrolling up a bit, and for me, currently in line 43 is where I’m returning the f-string for .__str__() of the Animal class.

01:38 And here I say, jumps over the lazy dog, and instead of the lazy dog of the farm, I’m just going to put in the location here. Jumps are not really over.

01:48 So it jumps in the self._location

01:57 And here I’m going to run into an issue because this is either None or it’s a location object. So I don’t really want the printout of the whole location object.

02:06 I just kind of want the output of the location type. But the problem if I do .location_type here is that if I want to print an Animal before it has an object assigned to that attribute, this is going to fail.

02:23 Let’s try it out and then figure out how we can improve that. So if I save this and then try to do the same thing again, create a dog and then print the dog,

02:36 then I run into to an AttributeError: 'NoneType' object has no attribute 'location_type'. This is because self._location at the beginning is None, and then this f-string can’t get properly constructed here on line 43 if it doesn’t have a location.

02:53 So if I say field,

02:58 big field, and dog.move() into the field,

03:05 then printing out the dog instance should work nicely. The happy black dog Puppy jumps in the field. This is the output that I want, right?

03:13 But it only works if ._location references a location object. Now what if I just take away .location_type and just print out ._location, and it would be None at first, but then it would point to an object.

03:30 Try that out because it might surprise you what you can see happen there. We need another dog

03:40 and a field.

03:45 And so if I print the dog now, then this is okay. The happy black dog Puppy jumps in the None. Doesn’t mean much, it’s not grammatically correct, but it’s not an error.

03:57 So I could potentially live with that. However, if now I move the dog to the field

04:04 and now try to print the instance again, I get strange output. The happy black dog Puppy jumps in the The field has one 1/10 spaces filled.

04:14 So this is the .__str__() of the Field object. And that’s just because the f-string calls the .__str__() method of every object to get its string representation, right?

04:27 And for the Field object, that’s the string representation that we defined earlier: The field has so and so many spaces out of so and so many spaces filled. This is why it’s more readable if you actually just get the .location_type, but then we have an issue with None.

04:44 There’s lots of ways that you could solve this, of course. I think I’m going to do it by introducing a new property. Probably that’s going to be the location, and that just gives back the .location_type if it references a location object. Sounds probably more complicated than it is. Let’s go do it in the next lesson.

Become a Member to join the conversation.