livepython.net
CHAPTER 20Object-Oriented Programming (Classes)
20.3  METHODS

Python Methods: Functions Inside a Class

What Is a Method in Python?

A method is a function that lives inside a class. It describes something the object can do. You call it on an object with a dot: rocky.bark().

Think of it like the buttons on a TV remote. Every remote of the same model has the same buttons. But when you press "volume up" on yours, only your TV gets louder, not your neighbour's.

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

    def bark(self):
        print(self.name, "says Woof!")

rocky = Dog("Rocky")
lucky = Dog("Lucky")
rocky.bark()
lucky.bark()
OUTPUT
Rocky says Woof!
Lucky says Woof!

The rules

  • Define a method with def inside the class, indented under it.
  • Its first parameter is always self, just like __init__.
  • Call it with object.method(). Python passes the object in as self, so rocky.bark() runs bark with self as Rocky.
  • Inside the method, self.name reaches the object's own attributes.
  • Leave one blank line between the methods of a class (PEP 8, chapter 16).

You've called methods before

"sunny".upper(), pets.append("Rocky") and line.split() are all methods of built-in classes. Now you can write your own.

FunctionMethod
defined on its own, with no indentdefined inside a class
called by its name: greet()called on an object: rocky.bark()
gets values only from its argumentsalso gets the object, as self

Avoid: forgetting self

PYTHONedit me
class Dog:
    def bark():
        print("Woof!")

rocky = Dog()
rocky.bark()
OUTPUT
TypeError: Dog.bark() takes 0 positional arguments but 1 was given

"1 was given", even though the brackets are empty? That one is the object, passed in as self. Add self to the def line.

A method is a function inside a class. Call it on an object, and it gets that object as self.

your turnPredict the output

What will this print?

class Cat: def __init__(self, name): self.name = name def meow(self): print(self.name + ": Meow") a = Cat("Lucky") b = Cat("Sunny") b.meow() a.meow()
Your turn! What will this code show on the screen?
your turnOrder the lines

Put the lines in order to print: Beep! Hello

  1. def greet(self):
  2. robo.greet()
  3. print("Beep! Hello")
  4. robo = Robot()
  5. class Robot:
These lines are mixed up. Put them back in order, then press Check.

Methods That Change Attributes

A method can change the object's attributes through self. This is how objects keep track of things over time: a bank account's balance, a player's score, a pet's hunger.

Think of it like a step counter on your wrist. Each step makes it add one to its count. You never type the number in yourself; the counter keeps its own count up to date.

PYTHONedit me
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

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

    def withdraw(self, amount):
        self.balance -= amount

sunny = BankAccount("Sunny")
sunny.deposit(500)
sunny.withdraw(200)
sunny.deposit(50)
print(sunny.owner, sunny.balance)
OUTPUT
Sunny 350

The rules

  • A method can take more parameters after self: deposit(self, amount).
  • Pass only the extra values in the call: sunny.deposit(500). Python fills in self.
  • self.balance += amount changes the attribute inside this object. The change stays after the method ends.
  • A method only changes the object it was called on:
PYTHONedit me
class Player:
    def __init__(self, name):
        self.name = name
        self.score = 0

    def add_points(self, points):
        self.score += points

rocky = Player("Rocky")
lucky = Player("Lucky")
rocky.add_points(10)
rocky.add_points(5)
lucky.add_points(7)
print(rocky.score, lucky.score)
OUTPUT
15 7

Why a method, and not the attribute directly?

You could write sunny.balance += 500 from outside the class. But a method keeps the rules for a change in one place. Later, when deposits need a check (no negative amounts) or a line in a history list, you change one method, and every deposit in the program follows the new rule.

Avoid: forgetting self. inside the method

PYTHONedit me
class Player:
    def __init__(self, name):
        self.name = name
        self.score = 0

    def add_points(self, points):
        score += points

rocky = Player("Rocky")
rocky.add_points(10)
OUTPUT
UnboundLocalError: cannot access local variable 'score' where it is not associated with a value

Don't be scared of this one! Without self., Python thinks score is a new local variable of the method, and it has no value yet. You meant the attribute: self.score.

Methods change an object's attributes through self, so the object keeps its own data up to date.

your turnFill the gap

Complete the add method

class Wallet: def __init__(self): self.money = 0 def add(self, amount): ? += amount w = Wallet() w.add(20) print(w.money)

It should print: 20

Which piece makes this code work?
your turnType the output

Type what this prints

class Counter: def __init__(self): self.count = 0 def click(self): self.count += 1 c = Counter() c.click() c.click() c.click() print(c.count)
Read the code line by line, then type the output exactly.

Methods That Return Values

A method can return a value, just like the functions in chapter 15. Use it when you want an answer from the object: an area, an average, a yes or no.

Think of it like asking a shop assistant, "How much is this?" They don't change anything in the shop. They look, tell you the answer, and you decide what to do with it.

PYTHONedit me
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

room = Rectangle(4, 3)
print(room.area())
print(room.perimeter())
print("Tiles needed:", room.area() * 2)
OUTPUT
12
14
Tiles needed: 24

The rules

  • return hands a value back, and the call room.area() becomes that value.
  • Store it, print it, or use it in a calculation, like any returned value.
  • A method can return True or False to answer a yes or no question. Name it like a question: is_passing(), can_vote().
  • One method can call another through self: self.average().
PYTHONedit me
class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def average(self):
        return sum(self.marks) / len(self.marks)

    def is_passing(self):
        return self.average() >= 40

sunny = Student("Sunny", [70, 85, 60])
print(f"{sunny.average():.2f}")
if sunny.is_passing():
    print(sunny.name, "passed")
OUTPUT
71.67
Sunny passed

is_passing() doesn't repeat the maths. It asks self.average(), and compares the answer with 40.

Change or answer?

A method that...Usually...Example
changes the objectreturns nothingdeposit(amount)
answers a questionreturns a value and changes nothingarea()

Common mistake: forgetting the brackets. room.area without () doesn't run the method. Printing it shows something like <bound method Rectangle.area of ...> instead of a number. The brackets are what run it.

A method that returns a value answers a question about its object. Call it with brackets.

your turnPredict the output

What will this print?

class Box: def __init__(self, size): self.size = size def double(self): return self.size * 2 b = Box(5) b.double() print(b.size)
Your turn! What will this code show on the screen?
your turnPick the right idea

A Student class needs a method that tells the program if the student passed. What should the method do?

Think about it, then pick one.

Methods That Check Values and Raise Errors

A good method protects its object. Before it changes an attribute, it checks the value with if, and it can raise an error when the change makes no sense, as you learned in chapter 17.

Think of it like an ATM. You can ask it for money, but it checks your balance first. It says "no" instead of handing out money you don't have.

PYTHONedit me
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("Not enough money")
        self.balance -= amount

rocky = BankAccount("Rocky", 100)
rocky.withdraw(30)
print(rocky.balance)
rocky.withdraw(500)
print(rocky.balance)
OUTPUT
70
ValueError: Not enough money

The second withdrawal stopped the program before the balance could go below zero. The last line never ran.

Catch it with try and except

The code that calls the method decides what to do about the error:

PYTHONedit me
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("Not enough money")
        self.balance -= amount

rocky = BankAccount("Rocky", 100)
try:
    rocky.withdraw(500)
except ValueError:
    print("Sorry, Rocky doesn't have that much.")
print("Balance:", rocky.balance)
OUTPUT
Sorry, Rocky doesn't have that much.
Balance: 100

The rules

  • Check first, change after. If the check fails, raise stops the method before anything changes.
  • Use a clear message: ValueError("Not enough money") tells the reader what went wrong.
  • The method raises; the caller catches with try and except. Either way, the object stays correct.
  • __init__ can check its values too: a negative starting balance can raise an error.

Common beginner doubt: "Why raise instead of printing a message?" A print inside the method can't stop the rest of the program, and the code that called it never learns that something went wrong. An error can't be missed: the caller must handle it, or the program stops.

Check the value, raise if it's wrong, then change the attribute. The caller decides how to handle the error.

your turnPredict the output

What will this print?

class Wallet: def __init__(self, money): self.money = money def spend(self, amount): if amount > self.money: raise ValueError("Too much") self.money -= amount w = Wallet(50) try: w.spend(20) w.spend(40) except ValueError: print("Stopped") print(w.money)
Your turn! What will this code show on the screen?
your turnType the output

Remember try, except and finally?

try: print(int("ten")) except ValueError: print("Not a number") finally: print("Done")
Read the code line by line, then type the output exactly.

Practice: Methods

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

  1. 184.Python Program to Find Area and Perimeter Using a ClassEasySolve
  2. 185.Python Program to Make a Bank Account ClassMediumSolve