Skip to content

Python Instance, Class and Static Methods

Updated 7 min read Aimerscrew

Every method you've written so far has started with self. Those are instance methods, and they're the most common kind. But Python has two more: class methods and static methods. Knowing when to use Python class and static methods helps you write classes that are cleaner and easier to use. In this lesson, you'll compare all three, build alternative constructors with @classmethod, and group helper functions with @staticmethod.

🌍 Real-life example

At a pizza restaurant, a waiter handles your specific order: "add extra cheese to this pizza" (an instance method). The menu offers ready-made recipes like "Margherita" that create a new pizza for you (a class method). And there's a kitchen timer that converts minutes to seconds; it doesn't care about any particular pizza or the menu at all (a static method).

What are the three types of methods in Python?

The difference comes down to what the method receives automatically as its first argument:

  • Instance method: receives the object as self. It can read and change that object's data.
  • Class method: marked with @classmethod, receives the class as cls. It works with the class, not one object.
  • Static method: marked with @staticmethod, receives nothing extra. It's a normal function that lives inside the class for organization.
Three columns. Instance method: called as pizza.add_topping(), Python passes the object as self. Class method: called as Pizza.margherita(), Python passes the class Pizza as cls. Static method: called as Pizza.minutes_to_seconds(12), Python passes nothing extra.
What each kind of method receives automatically when you call it.

The @ lines are called decorators. They change how the function below them behaves. You'll learn to write your own in Python decorators; for now, just know that @classmethod and @staticmethod are built in.

Instance methods: working with one object

An instance method is any normal method with self as its first parameter. Use it whenever the method needs the object's own data.

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    def add_topping(self, topping):
        self.toppings.append(topping)

    def describe(self):
        print(f"{self.size} pizza with {', '.join(self.toppings)}")

order = Pizza("Large", ["cheese"])
order.add_topping("mushrooms")
order.describe()
Large pizza with cheese, mushrooms

What is a class method in Python?

A class method receives the class itself as its first argument, named cls by convention. Since cls is the class, calling cls(...) creates a new object, just like writing Pizza(...). That makes class methods perfect for alternative constructors: extra, ready-made ways to create objects.

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    @classmethod
    def margherita(cls, size="Medium"):
        return cls(size, ["tomato", "mozzarella", "basil"])

    @classmethod
    def pepperoni(cls, size="Medium"):
        return cls(size, ["tomato", "mozzarella", "pepperoni"])

    def describe(self):
        print(f"{self.size} pizza with {', '.join(self.toppings)}")

dinner = Pizza.margherita()
party = Pizza.pepperoni("Large")

dinner.describe()
party.describe()
Medium pizza with tomato, mozzarella, basil
Large pizza with tomato, mozzarella, pepperoni

Notice you call class methods on the class: Pizza.margherita(). You don't need an object first. The names also make your code read like plain English.

Building objects from a string with from_string()

A very common alternative constructor reads data in another format, such as a line from a CSV file. By convention these are named from_something:

class Employee:
    def __init__(self, name, role, salary):
        self.name = name
        self.role = role
        self.salary = salary

    @classmethod
    def from_string(cls, text):
        name, role, salary = text.split(",")
        return cls(name, role, int(salary))

row = "Ana Silva,Designer,52000"
ana = Employee.from_string(row)

print(ana.name)
print(ana.role)
print(ana.salary + 1000)
Ana Silva
Designer
53000

The parsing logic lives in one place, inside the class, instead of being repeated everywhere you read employee data.

💡 Tip

Inside a class method, write cls(...) rather than the class name. If you later create a child class with inheritance, cls automatically becomes the child class, so Manager.from_string(...) returns a Manager, not an Employee.

Class methods can also use class attributes

Because a class method has cls, it can read and change class attributes that every object shares:

class Pizza:
    base_price = 10

    @classmethod
    def change_base_price(cls, new_price):
        cls.base_price = new_price
        print("All pizzas now start at $", cls.base_price)

Pizza.change_base_price(12)
print(Pizza.base_price)
All pizzas now start at $ 12
12

What is a static method in Python?

A static method receives neither self nor cls. It's an ordinary function that you place inside a class because it's closely related to that class. It can't see any object or class data unless you pass it in.

class Temperature:
    @staticmethod
    def c_to_f(celsius):
        return celsius * 9 / 5 + 32

    @staticmethod
    def f_to_c(fahrenheit):
        return round((fahrenheit - 32) * 5 / 9, 1)

print(Temperature.c_to_f(25))
print(Temperature.f_to_c(98.6))
77.0
37.0

You could write these as plain functions outside any class, and that would be fine too. Putting them inside Temperature simply groups related tools under one clear name.

Using a static method as a helper

Static methods are often small helpers that other methods in the class use, like validation checks:

class User:
    def __init__(self, email):
        if not User.is_valid_email(email):
            raise ValueError("Invalid email: " + email)
        self.email = email

    @staticmethod
    def is_valid_email(email):
        return "@" in email and "." in email.split("@")[-1]

print(User.is_valid_email("kim@example.com"))
print(User.is_valid_email("kim.example.com"))

user = User("kim@example.com")
print(user.email)

User("oops")
True
False
kim@example.com
ValueError: Invalid email: oops

You can call a static method on the class (User.is_valid_email(...)) or on an object (user.is_valid_email(...)); both work the same way.

Instance vs class vs static methods: comparison

Instance methodClass methodStatic method
DecoratorNone@classmethod@staticmethod
First parameterself (the object)cls (the class)None
Can use object data?YesNoNo
Can use class data?Yes (through self)YesNo (unless passed in)
Usually called onAn object: order.describe()The class: Pizza.margherita()Either: Temperature.c_to_f(25)
Typical useMost behavior of an objectAlternative constructors, class-wide settingsHelpers and utilities related to the class

How do you choose which method to use?

Ask yourself one question: what does this method need?

  • It needs this object's data → instance method.
  • It needs the class, for example to create new objects or change shared settings → class method.
  • It needs neither, only its own arguments → static method.

Common mistakes

1. Forgetting the decorator

class Temperature:
    def c_to_f(celsius):           # missing @staticmethod
        return celsius * 9 / 5 + 32

t = Temperature()
print(t.c_to_f(25))
TypeError: Temperature.c_to_f() takes 1 positional argument but 2 were given

Without @staticmethod, Python treats it as an instance method and passes the object as the first argument, so 25 becomes a second, unexpected argument.

2. Trying to use self in a static or class method

class Pizza:
    def __init__(self, size):
        self.size = size

    @staticmethod
    def show_size():
        print(self.size)

Pizza("Small").show_size()
NameError: name 'self' is not defined

Static and class methods don't receive the object. If a method needs the object's data, make it an instance method.

3. Calling an instance method on the class

class Pizza:
    def __init__(self, size):
        self.size = size

    def describe(self):
        print(self.size, "pizza")

Pizza.describe()
TypeError: Pizza.describe() missing 1 required positional argument: 'self'

Instance methods need an object. Create one first: Pizza("Small").describe().

Practice exercise

🏋️ Try it yourself

Create a Song class with title, artist and seconds. Add a class method from_string() that accepts text like "Blue Sky|Nova|215", a static method format_time(seconds) that returns a string like "3:35", and an instance method show() that prints Blue Sky by Nova (3:35) using the static method.

Show solution
class Song:
    def __init__(self, title, artist, seconds):
        self.title = title
        self.artist = artist
        self.seconds = seconds

    @classmethod
    def from_string(cls, text):
        title, artist, seconds = text.split("|")
        return cls(title, artist, int(seconds))

    @staticmethod
    def format_time(seconds):
        return f"{seconds // 60}:{seconds % 60:02d}"

    def show(self):
        print(f"{self.title} by {self.artist} ({Song.format_time(self.seconds)})")

song = Song.from_string("Blue Sky|Nova|215")
song.show()
print(Song.format_time(65))
Blue Sky by Nova (3:35)
1:05

What's next?

You've seen cls adapt automatically to child classes. Now it's time to learn how child classes work: Python inheritance lets one class reuse and extend another.

Key takeaways

  • Instance methods take self and work with one object's data. They are the default kind of method.
  • Class methods use @classmethod and take cls, the class itself, so they can create objects or change class attributes.
  • Class methods are commonly used as alternative constructors, such as Pizza.margherita() or Employee.from_string(text).
  • Static methods use @staticmethod and take neither self nor cls; they are helper functions grouped inside a class.
  • Use cls(...) inside class methods so they also work correctly for child classes.
  • Choose by asking what the method needs: the object, the class, or neither.

Frequently asked questions

What is the difference between @classmethod and @staticmethod in Python?

A class method receives the class as its first argument (cls), so it can create objects and use class attributes. A static method receives no automatic argument and cannot access the class or object unless you pass them in.

When should I use a class method in Python?

Use a class method when the method needs the class rather than a specific object, most often for alternative constructors like from_string() or for changing settings shared by all objects.

When should I use a static method in Python?

Use a static method for a helper that is related to the class but does not need any object or class data, such as a unit converter or a validation check.

What does cls mean in Python?

cls is the conventional name for the first parameter of a class method. It refers to the class the method was called on, so cls(...) creates a new object of that class.

Can a static method be called from an object?

Yes. You can call a static method on the class, like Temperature.c_to_f(25), or on an object, like t.c_to_f(25). Both behave the same because no automatic argument is passed.