staticmethod vs. classmethod in Python

Choose a static method for class-related logic without implicit state, or a class method when you need the calling class and subclass-aware construction.

Best practices
staticmethod vs. classmethod in Python illustration

A @staticmethod receives no implicit first argument. A @classmethod receives the calling class as cls. Use the former for related utility logic and the latter when the operation needs the class itself.

Compare the two methods

class Date:
    def __init__(self, year, month):
        self.year, self.month = year, month

    @staticmethod
    def is_valid(year, month):
        return year >= 1900 and 1 <= month <= 12

    @classmethod
    def from_string(cls, value):
        year, month = value.split('-')
        return cls(int(year), int(month))

assert Date.is_valid(2024, 6)
date = Date.from_string('2024-06')

is_valid() needs only its explicit arguments. from_string() constructs an instance through cls, making it an alternate constructor. This small example parses year and month; it does not automatically call is_valid() or implement full calendar validation.

Choose based on the state you need

Use a static method when the function belongs with the class conceptually but needs neither instance state nor an implicitly supplied class. A module-level function is also reasonable if putting it on the class adds little clarity.

Use a class method for class-level behavior, including alternate constructors that should respect inheritance. Use an ordinary instance method when the operation needs self and its state.

FAQ

Can I call a static method through an instance?

Yes. Python permits both Date.is_valid(...) and date.is_valid(...); neither passes the instance. Calling it through the class usually makes that behavior clearer.

How does a class method behave with inheritance?

class ReportingDate(Date):
    pass

value = ReportingDate.from_string('2024-06')
assert isinstance(value, ReportingDate)

cls is ReportingDate in this call. The inherited constructor remains useful as long as the subclass accepts the arguments it supplies.

See Python built-in functions.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting