Locked learning resources

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

Unlock This Lesson

Locked learning resources

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

Unlock This Lesson

Default Methods

00:00 Welcome to the next lesson in Object-Oriented Programming in Python versus Java. In this lesson, we’ll take a look at some of the default methods that all Python objects inherit.

00:13 In Java, we are familiar with the .toString() method. It is a method inherited from the Java class Object and the value it returns isn’t very interesting.

00:24 It’s not very useful, it doesn’t tell us much, so we typically override it. Here’s an example .toString() method that we might create in Java for our Car.

00:35 We say "Car" and then we specify its color, its model, and its year.

00:42 Python has something similar, and that’s the .__str__() string method. It’s inherited from Python’s Object class and its default implementation is about as useful as Java’s.

00:57 So again, it’s overridden with a method defined as a dunder method—beginning and ending with two underscores—the .__str__() method. And when we use it, we actually have to explicitly state that we want to use the str() (string) method.

01:14 It won’t happen automatically like Java’s does sometimes when it’s in a System.out.println() call or things like that.

01:25 Here, I have added to my Car class the .__str__() method. It has to have a parameter, so you refer to the calling object. And it’s returning an f-string, formatted string, built up of the car’s color, model, and year.

01:43 So this format is going to match the same one that you saw for the Java class. And so this gives us a convenient way, now that we have defined it. So let’s see how that works. I will import the car module,

02:02 create my_car,

02:08 and now if I want to find out information about my_car using the string method that I just wrote,

02:16 f"My car is a"… Now, this is a little bit different. We’re going to use this like a function call, not a method call. We’ll say string—well, str()and then we put the name of our object as the parameter.

02:33 Again, not quite what we’re used to with method calls, but this is the syntax that .__str__() and a lot of the other default methods use. You don’t use the underscores. You use it as a function call.

02:48 And then there, I can see information about my_car.

02:55 There are other dunder methods that you inherit from Object in Python. One is called .__repr__(). It’s another string representation of the object, but it’s designed for debugging purposes.

03:10 And so how that might look—it might look the exact same way as your .__str__() method. But if your .__str__() method is phrased nicely for user output, you might have a more technical version in your .__repr__().

03:30 There’s also a .__hash__() method, similar to Java’s .hashcode(), many others. Some of them are used to overload operators in Python—something we can’t do in Java.

03:44 And that will be the subject of your next tutorial—overloaded operators.

Avatar image for Alain Rouleau

Alain Rouleau on July 1, 2021

Very much enjoyed the lectures but the built-in str() function is NOT required within the print() function in order to print a string of the my_car object.

When you call the print function it will check to see if you have overridden the __str__ method. If so then it will use the string you have decided to return. If not then it will use the default string. Either way there’s always a string as it relates to objects.

So, using the built-in str() function does no harm but in reality all you’re doing is just converting a string to a string.

Avatar image for Martin Breuss

Martin Breuss RP Team on July 2, 2021

Good point @Alain Rouleau, althought I’d argue you’re not converting a string to a string with using the str() method. The instance representation of your class is only generated when you’re calling the str() method on it, or when you’re passing the object to a print() call, which calls the str() method internally:

>>> class Car:
...     pass
... 
>>> c = Car()
>>> c
<__main__.Car object at 0x100ea6a90>
>>> print(c)
<__main__.Car object at 0x100ea6a90>
>>> type(c)
<class '__main__.Car'>
>>> type(print(c))
<__main__.Car object at 0x100ea6a90>
<class 'NoneType'>

However, there is a call to print() done in the example code shown in the video:

print(f"My car is a - {str(my_car)}")

So you’re right that the str() call isn’t necessary to get to the same result. print() will take care of that for you:

print(f"My car is a - {my_car}")

In fact, in this example the implicit conversion of your my_car object to its string representation happens even earlier than the print() call. Can you see where?

Become a Member to join the conversation.