livepython.net
CHAPTER 20Object-Oriented Programming (Classes)
20.4  __STR__

Python __str__ Method: Print Objects Nicely

What Happens When You Print an Object?

Print an object of your own class, and Python doesn't know what to show. It falls back to a default text: the class name and the object's memory address, the place where the object is stored in the computer's memory.

Think of it like a parcel with no label. The post office can tell you "a parcel, on shelf 7f3a", but not what's inside or who it's for.

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

rocky = Dog("Rocky", 3)
print(rocky)  # <__main__.Dog object at 0x7f8b2c3d4e50>

This example isn't live, because the address is different every time it runs. The comment shows one run's output.

Reading the default text

PartMeans
__main__.Dogthe class, from the file you're running
objectit's an object of that class
at 0x7f8b2c3d4e50its memory address, written in hexadecimal (counting in 16s)
  • The address changes on every run and every computer. It tells you nothing about Rocky.
  • The attributes aren't shown. Python can't guess which ones matter, or how to lay them out.
  • The default text isn't an error. The program keeps running.

The quick fix you already know

You can print the attributes yourself:

PYTHONedit me
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

rocky = Dog("Rocky", 3)
print(f"{rocky.name}, {rocky.age} years old")
OUTPUT
Rocky, 3 years old

This works, but you'd have to repeat that f-string everywhere you print a dog. In the next lesson, you'll teach the class to describe itself, once.

Printing an object with no __str__ shows its class and memory address, which is rarely what you want.

your turnPick the right idea

print(rocky) shows <__main__.Dog object at 0x7f8b2c3d4e50>. What does the 0x7f8b2c3d4e50 part tell you?

Think about it, then pick one.
your turnPredict the output

Remember f-string formatting?

price = 4.5 print(f"Price: {price:.2f}")
Your turn! What will this code show on the screen?

The __str__ Method in Python

The __str__ method tells Python what text to show for your object. Whenever you print() an object, Python calls its __str__ and prints the string it returns.

Think of it like a name badge at an event. Instead of a stranger guessing who you are, your badge says exactly what you chose: "Sunny, Python Club".

PYTHONedit me
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name}, {self.age} years old"

rocky = Dog("Rocky", 3)
lucky = Dog("Lucky", 5)
print(rocky)
print(lucky)
OUTPUT
Rocky, 3 years old
Lucky, 5 years old

The rules

  • Write def __str__(self): inside the class. Two underscores on each side, like __init__.
  • It takes only self.
  • It must return a string. It doesn't print anything itself.
  • You never call it by name. print(rocky) calls it for you.
  • Put the most useful facts in it: what you'd want to see when you print the object to check it.
PYTHONedit me
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount

    def __str__(self):
        return f"{self.owner} has {self.balance:.2f}"

sunny = BankAccount("Sunny", 20)
print(sunny)
sunny.deposit(5.5)
print(sunny)
OUTPUT
Sunny has 20.00
Sunny has 25.50

__str__ runs again on every print, so it always shows the latest values.

Common beginner doubt: "Do I have to write __str__ in every class?" No, but it's a good habit for any class you'll print. It makes testing and debugging (chapter 3) much easier: one print() shows you the whole object.

Add __str__ to a class to choose what print() shows: return a clear string built from the attributes.

your turnFill the gap

Complete the method so print(b) shows the book

class Book: def __init__(self, title): self.title = title def ?(self): return "Book: " + self.title b = Book("Python Basics") print(b)

It should print: Book: Python Basics

Which piece makes this code work?
your turnPredict the output

What will this print?

class Pet: def __init__(self, name): self.name = name def __str__(self): return "Pet: " + self.name p = Pet("Lucky") print(p) p.name = "Sunny" print(p)
Your turn! What will this code show on the screen?

str() and f-strings Use __str__ Too

print() isn't the only thing that uses __str__. str() and f-strings call it too. So once a class has __str__, its objects fit into any text you build.

Think of it like a business card. Once you have one, you can hand it to anyone, pin it on a board or tape it into a letter. You made it once, and it works everywhere.

PYTHONedit me
class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def __str__(self):
        return f"{self.name} ({self.marks})"

sunny = Student("Sunny", 82)
text = str(sunny)
print(text)
print(f"Top student: {sunny}")
print("Report: " + str(sunny))
OUTPUT
Sunny (82)
Top student: Sunny (82)
Report: Sunny (82)

Where __str__ is used

You writeWhat happens
print(sunny)Python calls __str__
str(sunny)Python calls __str__
f"Top: {sunny}"Python calls __str__
"Report: " + sunnya TypeError: wrap it in str()

Avoid: joining an object to a string with +

PYTHONedit me
class Student:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name

sunny = Student("Sunny")
print("Hello " + sunny)
OUTPUT
TypeError: can only concatenate str (not "Student") to str

It's the same as joining a number in chapter 5: + only joins strings. Wrap the object in str(), or use an f-string.

Printing many objects

To print a list of objects, loop over it and print each one:

PYTHONedit me
class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def __str__(self):
        return f"{self.name} ({self.marks})"

students = [Student("Sunny", 82), Student("Rocky", 67), Student("Lucky", 91)]
for student in students:
    print(student)
OUTPUT
Sunny (82)
Rocky (67)
Lucky (91)

Common beginner doubt: "Why not print(students)?" A list doesn't use __str__ for the things inside it. It would show the default text, with a memory address, for every student. Loop and print them one by one.

print(), str() and f-strings all use __str__. To print a list of objects, print them one at a time.

your turnType the output

Type what this prints

class Item: def __init__(self, name, price): self.name = name self.price = price def __str__(self): return f"{self.name}: {self.price:.2f}" pen = Item("Pen", 1.5) print(f"You bought {pen}")
Read the code line by line, then type the output exactly.
your turnOrder the lines

Put the lines in order to print: Hi, Robot R2

  1. return "Robot R2"
  2. def __str__(self):
  3. robo = Robot()
  4. class Robot:
  5. print("Hi, " + str(robo))
These lines are mixed up. Put them back in order, then press Check.

Common __str__ Mistakes

The __str__ method has one job: return a string. Almost every __str__ mistake breaks that rule. Here are the three you'll meet most, and how to read their errors.

Think of it like a waiter taking your order to the kitchen. The waiter has to hand the note to the chef. Shouting it in the hallway doesn't get it there, and neither does handing over a plate instead of a note.

Mistake 1: printing instead of returning

PYTHONedit me
class Dog:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        print("Dog:", self.name)

rocky = Dog("Rocky")
print(rocky)
OUTPUT
Dog: Rocky
TypeError: __str__ returned non-string (type NoneType)

The print() inside ran first. Then __str__ gave back nothing, which means None (chapter 15). print(rocky) needs a string, so Python stops. Change print to return.

Mistake 2: returning a number

PYTHONedit me
class Score:
    def __init__(self, points):
        self.points = points

    def __str__(self):
        return self.points

print(Score(10))
OUTPUT
TypeError: __str__ returned non-string (type int)

__str__ must give back text. Turn the number into a string: return str(self.points), or use an f-string.

Mistake 3: a typo in the name

class Dog:
    def __init__(self, name):
        self.name = name

    def _str_(self):
        return "Dog: " + self.name

print(Dog("Rocky"))  # <__main__.Dog object at 0x...>

No error, but no nice text either. With one underscore on each side, it's an ordinary method, and print() never calls it. You get the default text with a memory address.

RuleGoodAvoid
return, don't printreturn "Dog: " + self.nameprint("Dog:", self.name)
return a stringreturn str(self.points)return self.points
two underscores on each side__str___str_

__str__ must return a string. Return, don't print, and spell it with two underscores on each side.

your turnFix the code

Fix the code so it prints: Score: 10

It should print: Score: 10

class Score:
    def __init__(self, points):
        self.points = points

    def __str__(self):
        return self.points

print("Score:", Score(10))
This code does not work yet. Fix it, then press Run.
your turnPick the right idea

Which line is a correct body for __str__ in a Cat class?

Think about it, then pick one.

Practice: __str__

Solve these to lock in what you learned in this topic. Each one runs in your browser.

  1. 186.Python Program to Print a Book Object Using __str__EasySolve
  2. 187.Python Program to Print a Shopping Cart of ObjectsMediumSolve