Attributes, Methods, and Object State

What an object knows and what it can do

Intermediate 10 min

In this lesson

In Python, an attribute is a piece of data stored on an object, and a method is an action that reads or updates that data. Together an object’s attributes make up its state — the information it holds, which can change as the program runs. In this lesson you’ll see how attributes store state, how methods change it safely, and why returning a value usually beats printing one.

Explain it like I’m 5

Attributes are what an object knows; methods are what it can do. A bank account knows its balance, and it can deposit or withdraw — each action changes what it knows.

Attributes hold state; methods change it

An attribute is a value stored on an object (like self.balance). Together, an object’s attributes are its state. A method is an action that reads or updates that state. Because the data and the actions live in the same object, you can trust that a deposit always updates the right balance.

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

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

acc = BankAccount("Ada", 100)
acc.deposit(50)
print(acc.owner, "has", acc.balance)
Output
Ada has 150
deposit() changes the object's state.

Return a value instead of printing inside a method

It’s tempting to print() from inside a method, but that locks the method into one use — displaying. If a method returns its result instead, the caller can print it, store it, or make a decision with it. Reserve printing for the outer layer of your program.

Example
class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def withdraw(self, amount):
        if amount > self.balance:
            return False
        self.balance -= amount
        return True

acc = BankAccount(100)
if acc.withdraw(150):
    print("Withdrawn")
else:
    print("Insufficient funds")
Output
Insufficient funds
Returning True/False lets the caller decide what to do.

Common mistake: Printing inside a method that should return a value

Why it happens:

Printing gives instant feedback while you’re experimenting, so it sneaks into methods permanently.

How to fix it:

Have the method return its result and let the caller decide whether to print it, store it, or branch on it. A method that returns is reusable; one that prints is stuck doing only that.

Common mistake: Changing an attribute from outside the object

Why it happens:

Writing acc.balance -= 50 directly seems simpler than calling a method.

How to fix it:

Go through a method like withdraw() so the object can enforce its own rules (no overdraft, no negative deposit). That’s the whole point of keeping behaviour with the data.

Common mistake: Letting state become invalid

Why it happens:

Skipping a check lets a negative deposit or an overdraft slip through, and later code trusts a balance that no longer makes sense.

How to fix it:

Guard the change: reject the bad value (return False or raise an error) before touching the attribute.

What is an object's state?

Why might withdraw() return False instead of printing an error?

After acc.deposit(25) on a balance of 100, what is acc.balance?

Mini exercise (medium)

Build a BankAccount class with deposit(amount) and withdraw(amount) methods. deposit should reject zero or negative amounts (return False), and withdraw should refuse to overdraw (return False). Both return True on success.

Do it here. Finish the code below and press Run to try your answer right in the browser — no setup needed.

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

    def deposit(self, amount):
        # TODO: reject amounts <= 0 (return False); otherwise add and return True
        pass

    def withdraw(self, amount):
        # TODO: reject overdrawing (return False); otherwise subtract and return True
        pass

acc = BankAccount(100)
print(acc.deposit(-5))
print(acc.deposit(50))
print(acc.withdraw(200))
print(acc.balance)

What to learn next

You learned that an object’s attributes are its state, that methods read and update that state, and why a method that returns a value is more reusable than one that prints. You built a BankAccount whose deposit and withdraw guard against bad input before changing the balance.

So far every attribute belonged to one object. Sometimes a value should be shared by all of them. Class Variables vs Instance Variables draws that line and shows the classic mutable class-variable trap. When you’re ready, continue to the next lesson.