Somebody asked a fair question in class this week: if add_hours(volunteer, 2) works perfectly well as a plain function, why go to the trouble of writing volunteer.log_shift(2) inside the class? Both change the same number. Both are one line.

The answer arrives about three weeks later, when a second file needs to add hours, and a third file needs to add hours differently, and nobody can find all the places that touch volunteer.hours. A method is a promise about where the rules live.

Attributes: what one object knows

Attributes are the variables that belong to an object. They are created with self. inside the class — usually in __init__, so that every object of the class starts life with the same set of them.

class Booking:
    """One room booking at the community centre."""
 
    def __init__(self, room, purpose, people):
        self.room = room
        self.purpose = purpose
        self.people = people
        self.confirmed = False

confirmed is not a parameter. Nobody books a room already confirmed, so the constructor decides it for everybody — that is what a constructor is for. Any rule that holds for every object of the class belongs there, written once.

Methods: what one object can do

A method is a function defined inside a class, whose first parameter is self.

    def confirm(self):
        """Confirm this booking. Returns False if it was already confirmed."""
        if self.confirmed:
            return False
        self.confirmed = True
        return True
 
    def size_note(self):
        """Describe the group size in words the front desk uses."""
        if self.people <= 6:
            return "small group"
        if self.people <= 20:
            return "standard"
        return "large group - needs the hall"

self is not magic and it is not a keyword; it is a parameter, and Python fills it in for you. When you write choir.confirm(), Python calls confirm(choir). Everything the method touches through self belongs to that one object, which is why confirming the choir does not confirm the tutoring session.

In the classAt the call siteWhat Python does
def confirm(self):choir.confirm()Passes choir in as self
self.people—Reads this booking’s size
return Trueif choir.confirm():Hands the answer to the caller
def __init__(self, ...)Booking("Hall", ...)Builds, then initialises
def __str__(self):print(choir)Supplies the printable form

Why the behaviour goes inside

The rule “more than twenty people needs the hall” is a fact about bookings. Put it in size_note and there is exactly one place to change it when the centre reopens the gym. Put it in four if statements across three files and you have the parallel-lists problem again, one level up.

Two habits that keep methods honest:

  • Methods return; the program prints. A method that prints can only ever be used one way. A method that returns can be printed, stored, tested, or sent to a web page. The one exception is a method written to display something, and it should say so in its name.
  • Docstrings, not guesswork. The triple-quoted line under def is what help(Booking.confirm) shows and what your teammate reads at 11 p.m. Say what it returns and when it refuses — that is the documentation expectation, and it costs eight seconds.

Write your first methods in Your First Class, see two classes call each other’s methods in A Program with Two Classes, and drill the mechanics in Methods and Encapsulation Practice. When somebody else’s method does something you did not expect, Trace It is the routine that finds out what self really was.

Curriculum connection

C1.1

decompose a problem into modules, classes, or abstract data types (e.g., stack, queue, dictionary) using an object-oriented design methodology (e.g., CRC [Class Responsibility Collaborator] or UML [Unified Modeling Language]);

Link to original

C1.3

demonstrate the ability to apply the process of functional decomposition in subprogram design;

Link to original

A4.3

create fully documented program code according to industry standards (e.g., doc comments, docstrings, block comments, line comments);

Link to original