ComparisonConcepts

Python @staticmethod vs @classmethod: What Is the Difference?

Short answer
A @classmethod receives the class itself as its first argument (cls) and can create or configure instances, while a @staticmethod receives no automatic argument and is just a regular function placed inside the class for organisation.

A normal method receives the instance as self. Sometimes the behaviour you want belongs to the class as a whole, not to one object. Python offers two decorators for that. Both can be called on the class without creating an object, but they differ in what they can reach: a class method knows which class it was called on, a static method knows nothing about the class or any instance.

The basics are in class and static methods. Since the decorators build on Python decorators, it helps to know how they wrap a function. For the instance-method side, see function vs method.

@staticmethod vs @classmethod compared

What each kind of method receives and can use.
AspectInstance method`@classmethod``@staticmethod`
First parameterself (the instance)cls (the class)None added automatically
Can read instance attributesYesNoNo
Can read class attributesYes, via selfYes, via clsOnly by writing the class name
Callable on the classOnly with an instance passed inYesYes
Works correctly with subclassesYesYes: cls is the subclassNot aware of the subclass
Typical useBehaviour of one objectAlternative constructors, class-wide settingsUtility helpers related to the class

When to use @classmethod

Use @classmethod for alternative constructors (often called factory methods) and for code that must work on the class's own data. A classic example is Student.from_string("Asha,20") that parses text and returns a new Student. Because it uses cls(...) rather than hard-coding the class name, a subclass that inherits it gets back an object of the subclass. See inheritance for why that matters.

When to use @staticmethod

Use @staticmethod when a function is logically part of the class but needs neither the instance nor the class, such as a validation helper Student.is_valid_age(20). Putting it inside the class keeps related code together and makes it discoverable. If the function has no connection to the class at all, a plain module-level function is usually even simpler.

How the decorators change the call

Without a decorator, calling a method on an instance passes the instance in. @classmethod swaps that for the class, and @staticmethod turns the automatic argument off, so the function behaves exactly as if it was defined outside the class. Both can be called through an instance too (s.is_valid_age(20) works), but the instance is ignored. A common design rule: if you find yourself writing ClassName.something inside a static method, make it a class method instead.

Examples you can run

Press Run, then edit the code and run it again.

@classmethod as an alternative constructor

from_string builds a Student from text. The class method receives cls and calls it like a constructor.

@classmethod as an alternative constructor
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

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

s = Student.from_string("Asha,20")
print(s.name, s.age)
Expected outputAsha 20

@staticmethod as a helper inside the class

is_valid_age uses only its argument. It gets no self or cls.

@staticmethod as a helper inside the class
class Student:
    @staticmethod
    def is_valid_age(age):
        return 5 <= age <= 100

print(Student.is_valid_age(20))
print(Student.is_valid_age(3))
Expected outputTrue
False

cls follows the subclass

The same class method returns an object of whichever class it was called on.

cls follows the subclass
class Student:
    def __init__(self, name):
        self.name = name

    @classmethod
    def create(cls, name):
        return cls(name)

class Intern(Student):
    pass

print(type(Student.create("Asha")).__name__)
print(type(Intern.create("Ravi")).__name__)
Expected outputStudent
Intern

A class method can change class-wide data

cls.count belongs to the class, so one call updates the shared counter.

A class method can change class-wide data
class Order:
    count = 0

    @classmethod
    def register(cls):
        cls.count += 1
        return cls.count

Order.register()
print(Order.register())
Expected output2

Common mistakes

Forgetting @staticmethod on a helper without self

✗ Wrong

class Student:
    def is_valid_age(age):
        return 5 <= age <= 100

print(Student().is_valid_age(20))
TypeError: Student.is_valid_age() takes 1 positional argument but 2 were given

✓ Right

class Student:
    @staticmethod
    def is_valid_age(age):
        return 5 <= age <= 100

print(Student().is_valid_age(20))

Add @staticmethod above the method, or give it a self parameter.

Using cls inside a static method

✗ Wrong

class Order:
    count = 3

    @staticmethod
    def show():
        return cls.count

print(Order.show())
NameError: name 'cls' is not defined

✓ Right

class Order:
    count = 3

    @classmethod
    def show(cls):
        return cls.count

print(Order.show())

A static method receives no cls. Switch to @classmethod when you need the class.

Using self inside a class method

✗ Wrong

class Order:
    @classmethod
    def label(cls):
        return self.name

Order.label()
NameError: name 'self' is not defined

✓ Right

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

    def label(self):
        return self.name

print(Order("A1").label())

A class method has no instance. Use an instance method if you need instance attributes.

Python @staticmethod vs @classmethod: What Is the Difference?: questions people ask

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

A class method automatically receives the class as cls, so it can create instances or change class-level data, while a static method receives nothing automatically and behaves like a plain function inside the class.

When should I use @classmethod instead of @staticmethod?

Use @classmethod when the method needs the class, typically for factory methods such as from_string() or for class-wide counters. Use @staticmethod only for helpers that need neither the class nor an instance.

Can a static method be called on an instance?

Yes. obj.helper() works for both static and class methods, but the instance is ignored and nothing extra is passed in. Calling through the class name, ClassName.helper(), makes the intent clearer.

Keep learning

Step-by-step lessons:
Python Class Methods and Static MethodsPython Classes and ObjectsPython Decorators

Related:
Python Function vs Method: What Is the Difference?Python OOP Cheat Sheet: Classes, Inheritance, Dunder MethodsPython print() vs return: What Is the Difference?Python str() vs repr(): What Is the Difference?

More in concepts:
Python Function vs Method: What Is the Difference?Python Module vs Package: What Is the Difference?Python Iterator vs Generator: What Is the Difference? See all →