Classes

INPUT · Slides

Making it printable as it is

01 / 07

Print a whole instance and

So far you have shown attributes one at a time, as in print(member.name). What happens if you hand the whole thing over with print(member)?

What comes out is this.

<__main__.Member object at 0x7f3a1c0d2e50>

It means "a real one of the class Member is being kept around here in memory". Not a lie, but not text meant for a person to read.

02 / 07

And it changes every time you run it

The awkward part is that the 0x7f3a... on the end changes every time you run it. It is the address of wherever it happens to be kept.

So no program can lean on that display, and this course cannot mark against it either. That is why every lesson so far has told you not to print an instance as it is.

03 / 07

Defining __str__

Write a method called __str__ inside the class and that is what gets used when you print.

As the two underscores on each side suggest, this is another name Python calls at a set moment. There is no need to call member.__str__() yourself.

class Member:    def __init__(self, name, years):        self.name = name        self.years = years    def __str__(self):        return f"{self.name} (member, year {self.years})"member = Member("Aoi", 3)print(member)

Result

Aoi (member, year 3)

04 / 07

Always return a string

Inside __str__ you hand back a string with return. Slip and call print instead and there is nothing left to hand back, so you get an error.

The job of __str__ is not to show something. It is to build the text that gets shown and pass it on.

class Member:    def __init__(self, name):        self.name = name    def __str__(self):        print(self.name)member = Member("Aoi")print(member)

Result

Aoi
TypeError: __str__ returned non-string (type NoneType)

05 / 07

Returning a number will not do either

What you return has to be a string. Even when all you want to show is the years, handing back the number gets you the same TypeError.

Turn it into text with str(), or drop it into an f-string.

class Member:    def __init__(self, years):        self.years = years    def __str__(self):        return str(self.years) + " years"member = Member(3)print(member)

Result

3 years

06 / 07

It is used inside f-strings too

__str__ is not called only by print. It is used when you hand something to str(), and when you write it inside the { } of an f-string.

Anywhere Python asks what this instance looks like as text, the same answer comes back.

class Member:    def __init__(self, name):        self.name = name    def __str__(self):        return f"{self.name} (member)"member = Member("Aoi")print(f"Welcome, {member}")

Result

Welcome, Aoi (member)

07 / 07

Where we have got to

You can now write a class that holds data, holds things it can do, and has a face people can read.

  • class … makes a blueprint
  • __init__ … settles the contents at the moment of birth
  • self … the particular real one being dealt with
  • a method … something that real one can do
  • __str__ … how it looks as text

The next group is inheritance, the way you write "almost the same, but slightly different". Starting from the member class, you will be able to build a premium member class.