@classmethod

A method that receives the class (cls) instead of an object. It is most often used as an alternative constructor.

On this page

Example

#
Python
class Student:
    def __init__(self, name, points):
        self.name = name
        self.points = points

    @classmethod
    def from_text(cls, text):
        name, points = text.split(";")
        return cls(name, int(points))

    @classmethod
    def from_dict(cls, data):
        return cls(data["name"], data.get("points", 0))

emma = Student.from_text("Emma;250")
jack = Student.from_dict({"name": "Jack"})

print(emma.name, emma.points)
print(jack.name, jack.points)
Resultsaved result, you can check it
Emma 250
Jack 0

Definition and usage

#

The @classmethod decorator creates a class method. Its first argument is not an object but the class itself, conventionally named cls. You usually call it through the class name, e.g. Student.from_text("Emma;250").

Its most common use is as an alternative constructor: a method that builds an object from data in a different format, such as a string, a dictionary, or a line from a file. The method prepares the arguments and finally calls cls(...). This is how the built-in dict.fromkeys() or datetime.fromisoformat() work.

Because cls points to the class the method was called on, in a derived class cls(...) creates an object of the derived class, not the base one. That is an advantage over a static method with a hardcoded class name. Class methods also have convenient access to class attributes, such as shared counters or settings.

Syntax

#
Syntax
class Name:
    @classmethod
    def method(cls, args):
        return cls(...)

Name.method(args)

More examples

#
cls in a derived class
Python
class Task:
    def __init__(self, number):
        self.number = number

    @classmethod
    def from_code(cls, code):
        return cls(code.removeprefix("task_"))

class Quiz(Task):
    pass

task = Quiz.from_code("task_7_3")
print(type(task).__name__, task.number)
Resultsaved result, you can check it
Quiz 7_3
Access to class attributes
Python
class Player:
    online = 0

    def __init__(self, nick):
        self.nick = nick
        Player.online += 1

    @classmethod
    def status(cls):
        return f"Players online: {cls.online}"

Player("emma_dev")
Player("jack99")
print(Player.status())
Resultsaved result, you can check it
Players online: 2

Good practices

#
  • Start alternative constructor names with from_, e.g. from_json() or from_row(). It is a convention familiar from the standard library.
  • In a class method, create objects through cls(...), not through the class name. That way it also works correctly in derived classes.
  • If a method needs neither the object nor the class, @staticmethod is enough.

Related entries

#

Spotted a mistake or missing an example? Write to us.