How to Create a Class in Python

What you’ll build or solve

You’ll create a Python class with attributes and methods, then instantiate it to make objects you can use in your code.

When this approach works best

This approach works best when you:

  • Keep passing around related data that belongs together, like a user’s name, email, and role.
  • Need reusable behavior tied to data, like Cart.add_item() or Timer.start().
  • Want a clean way to model real things in your app, like Student, Invoice, or GameCharacter.

Avoid this approach when:

  • You only need a simple container for values. A dictionary or tuple may be simpler.

Prerequisites

  • Python installed

Step-by-step instructions

1) Define a class with class

A class definition starts with class, a name in CapWords style, and a colon. The class body is indented.

class User:
    pass

Create an object (an instance) by calling the class:

user = User()
print(user)

What to look for: if the class body is not indented, you will get an IndentationError.


2) Add __init__ to store data on the instance

__init__ runs when you create a new instance. Use it to set attributes on self.

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

user = User("Mina", "mina@example.com")
print(user.name)
print(user.email)

What to look for: you do not pass self when you call User(...). Python passes it automatically.


3) Add methods for behavior and state changes

Methods are functions defined inside a class. They take self first so they can access and update instance data.

class Counter:
    def __init__(self, start=0):
        self.value = start

    def increment(self):
        self.value += 1
        return self.value

counter = Counter()
print(counter.increment())
print(counter.increment())

You can still update attributes directly, but methods help keep changes consistent:

counter.value = 10
print(counter.increment())

What to look for: if you forget self in a method definition, calling it usually raises a TypeError.


4) Create and use multiple instances

Each instance has its own separate data. Creating more than one instance is a quick way to confirm your class works as intended.

class User:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f"Hi, {self.name}!"

a = User("Mina")
b = User("Sam")

print(a.greet())
print(b.greet())

Each object keeps its own name.


Examples you can copy

Example 1: A simple class for holding data

class Product:
    def __init__(self, name, price_eur):
        self.name = name
        self.price_eur = price_eur

p = Product("Notebook", 4.5)
print(p.name, p.price_eur)

Example 2: A class with methods that update state

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

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

    def withdraw(self, amount):
        if amount > self.balance:
            return "Insufficient funds"
        self.balance -= amount
        return self.balance

acct = BankAccount("Mina", 50)
print(acct.deposit(25))
print(acct.withdraw(60))
print(acct.withdraw(10))

Example 3: A class that validates input

class Temperature:
    def __init__(self, celsius):
        if celsius < -273.15:
            raise ValueError("Temperature cannot be below absolute zero.")
        self.celsius = celsius

    def fahrenheit(self):
        return (self.celsius * 9 / 5) + 32

t = Temperature(20)
print(t.fahrenheit())

Example 4: Use inheritance to extend a class

Use inheritance when you have a clear “is-a” relationship.

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "..."

class Dog(Animal):
    def speak(self):
        return "Woof!"

pet = Dog("Rex")
print(pet.name, pet.speak())

Dog is an Animal, so it inherits name and overrides speak().


Common mistakes and how to fix them

Mistake 1: Forgetting self in a method

You might write:

class Greeter:
    def hello():
        return "Hello"

Why it breaks: Python passes the instance automatically when you call a method, but your method does not accept it.

Correct approach:

class Greeter:
    def hello(self):
        return "Hello"

g = Greeter()
print(g.hello())

Mistake 2: Setting attributes without self

You might write:

class User:
    def __init__(self, name):
        name = name

Why it breaks: you assign to a local variable, not to the instance. The instance never gets a name attribute.

Correct approach:

class User:
    def __init__(self, name):
        self.name = name

u = User("Ada")
print(u.name)

Troubleshooting

  • If you see TypeError: __init__() missing ..., pass the required arguments when creating the instance.
  • If you see AttributeError: object has no attribute ..., check you set the attribute on self in __init__.
  • If you see TypeError: ... takes 0 positional arguments but 1 was given, you forgot self in a method definition.
  • If you see IndentationError, indent class and method bodies consistently, usually 4 spaces.
  • If you see unexpected shared data between instances, avoid using mutable default values like items=[] in __init__. Use None and set a new list inside the method instead.

Quick recap

  • Define a class with class Name: and indent the body.
  • Add __init__ to store data on self.
  • Add methods that take self first to use and update instance data.
  • Create instances by calling the class like Name(...).
  • Use inheritance only when you have a clear “is-a” relationship.