Python Methods

In the last lesson you learned about Class Variables, the data that every object of a class shares. Now we look at the other half of a class. It is not the data this time. It is the actions. How does an object actually do something with the data it holds? That is the job of a method. That is what this lesson is about.

🤔 Why Methods?

Picture a bank account. It has a balance. On its own that number just sits there. But an account is not only a number. You deposit money. You withdraw money. You check the balance. Those are actions, and they belong to the account.

Here is the pain. If you keep the balance in a plain variable, every change is loose code scattered around your program.

balance = 1000
balance = balance + 500 # a deposit, somewhere
balance = balance - 200 # a withdrawal, somewhere else

Nothing ties these together. Anyone can change balance to anything. They could even set it to a negative number. And there is no single place that owns the rules. The deposit logic and the account are strangers to each other.

The fix is a method. A method is a function defined inside a class that works on the object’s own data. So deposit and withdraw live right next to the balance they change. The account owns its own actions.

🧩 What Is a Method?

A method is just a function that lives inside a class. The one thing that makes it special is its first parameter, which is always self. self is the object the method is working on. Through self, the method can read and change that object’s data.

Think of it like a phone. The phone holds your contacts. “Call” is a method on the phone. When you press call, the phone uses its own contact list. It does not use some other phone’s list. self is how a method points at “this object, the one I belong to.”

Here is the basic shape of a class with one method.

class Account:
def __init__(self, balance):
self.balance = balance
def show_balance(self):
print("Balance:", self.balance)

A few things to notice here:

  • def show_balance(self): is a method, because it is defined inside the class.
  • Its first parameter is self, the account the method runs on.
  • Inside, self.balance reads the balance belonging to this account.
  • __init__ is also a method. It sets up the data when the object is born.

🏦 Building a BankAccount

Let’s build a real account with actions. It can deposit, withdraw, and show the balance. Here is the whole class first. Then we walk through it.

class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance = self.balance + amount
print(f"{self.owner} deposited {amount}. New balance: {self.balance}")
def withdraw(self, amount):
self.balance = self.balance - amount
print(f"{self.owner} withdrew {amount}. New balance: {self.balance}")
account = BankAccount("Alex", 1000)
account.deposit(500)
account.withdraw(200)

Now read it line by line:

  • __init__ runs when the account is created. It stores the owner’s name and the starting balance on self.
  • deposit takes an amount, adds it to self.balance, and prints the new balance.
  • withdraw takes an amount, subtracts it from self.balance, and prints the new balance.
  • account = BankAccount("Alex", 1000) makes one account. Alex starts with 1000.
  • account.deposit(500) calls the deposit method on that account.

When you run it, you get this.

Output

Alex deposited 500. New balance: 1500
Alex withdrew 200. New balance: 1300

See how each call changed the same account? The deposit pushed the balance to 1500. Then the withdrawal brought it down to 1300. The balance carried over between calls, because it lives on the object, not in a loose variable.

🤝 Where Did self Go?

Here is the part that confuses almost everyone at first. The method is defined with self, but you never pass it when you call.

Look again.

def deposit(self, amount): # two parameters here
...
account.deposit(500) # but you pass only one value

It looks like one value is missing. It is not. When you write account.deposit(500), Python quietly sends account in as self for you. So inside the method, self is account, and amount is 500. You only fill in the values after self.

That is the whole trick. The object before the dot becomes self inside the method.

Note

A simple way to read it. account.deposit(500) is really Python doing BankAccount.deposit(account, 500). The object on the left of the dot slides in as self.

🆚 Method vs Plain Function

A method and a plain function look almost the same. Both start with def. So what is the real difference?

  • A plain function stands on its own. You call it by name, and you hand it everything it needs.
  • A method belongs to an object. You call it through the object with a dot, and it already has access to that object’s data through self.

Here is the same job done both ways.

# Plain function: you must pass the balance in every time
def deposit(balance, amount):
return balance + amount
balance = 1000
balance = deposit(balance, 500)
# Method: the account already knows its own balance
account = BankAccount("Alex", 1000)
account.deposit(500)

The function has no memory of any account. You feed it the balance each time and catch the result yourself. The method already holds the balance inside the object. That is the difference. A method is wired to the object it lives on.

🧰 A Light Note on classmethod and staticmethod

The methods we wrote so far are called instance methods. They work on one object, the instance, through self. That is what you will use most of the time.

There are two other kinds you will meet later. Here is just enough to recognise them.

  • A classmethod works on the class itself, not one object. Its first parameter is cls, not self. You mark it with @classmethod above the def.
  • A staticmethod does not touch the object or the class at all. It is a plain helper that just happens to live inside the class. It takes neither self nor cls. You mark it with @staticmethod.

Here is a tiny taste, just so the words are not strange when you see them again.

# a fresh, minimal version of the class, just to show the two kinds
class BankAccount:
bank_name = "Global Bank"
@classmethod
def get_bank_name(cls):
return cls.bank_name
@staticmethod
def is_valid_amount(amount):
return amount > 0
print(BankAccount.get_bank_name())
print(BankAccount.is_valid_amount(-50))

The classmethod reads something shared by the whole class. The staticmethod is just a checker that needs no object. Running it prints this.

Output

Global Bank
False

Do not worry about mastering these now. For everyday classes, instance methods with self are what you reach for. We just wanted the names to feel familiar.

📋 The Three Kinds at a Glance

Keep this small table near you. It sorts out which is which.

Kind First parameter Works on
Instance method self One object
Class method cls The class itself
Static method None Nothing, just a helper

⚠️ Common Mistakes

A few traps catch people again and again. Watch for these.

  • Forgetting self in the method definition. Every instance method needs self as its first parameter, or Python complains the moment you call it.
# ❌ Avoid: no self, so the method cannot see the object
def deposit(amount):
self.balance = self.balance + amount
# ✅ Good: self is the first parameter
def deposit(self, amount):
self.balance = self.balance + amount
  • Forgetting self. inside the method when you mean the object’s data. Plain balance is a local variable that vanishes. self.balance is the value that lives on the object.
# ❌ Avoid: this changes a local copy, the object is untouched
def deposit(self, amount):
balance = balance + amount
# ✅ Good: change the value on the object
def deposit(self, amount):
self.balance = self.balance + amount
  • Calling the method without the object. A method runs through its object, like account.deposit(500). Calling deposit(500) on its own has no account to work on.

✅ Best Practices

Keep these habits and your methods stay clean.

  • Always make self the first parameter of an instance method. It is not optional.
  • Use self. whenever you read or change data that belongs to the object. That is how the change actually sticks.
  • Give methods clear action names, like deposit, withdraw, or show_balance. A method does something, so a verb fits well.
  • Keep each method focused on one job. If one method grows large, split the work into smaller methods and call them.
  • Let the object own its rules. Put the logic that changes the balance inside the account, not scattered around your program.

🧩 What You’ve Learned

✅ A method is a function defined inside a class that works on the object’s own data.

✅ Every instance method takes self first, and self is the object the method runs on.

✅ You call a method through the object with a dot, like account.deposit(500), and Python passes the object in as self for you.

✅ Use self.balance to read and change data that belongs to the object, so the change sticks.

✅ Besides instance methods, there are classmethod (works on the class, takes cls) and staticmethod (a plain helper, takes neither).

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What makes a function a method?

    Why: A method is a function defined inside a class; it works on the object's data through self.

  2. 2

    What is self in an instance method?

    Why: self refers to the specific object the method runs on, so it can read and change that object's data.

  3. 3

    When you call account.deposit(500), what gets passed in as self?

    Why: Python passes the object on the left of the dot in as self, so account becomes self inside the method.

  4. 4

    Inside a method, how do you change data that belongs to the object?

    Why: self.balance points at the value living on the object, so changing it actually sticks; a plain variable is just a local copy.

🚀 What’s Next?

You can now give your objects actions through methods. Next we look at how one class can build on another and reuse its data and methods, so you do not write the same code twice.

Inheritance

Share & Connect