Class and static methods
A class method is a method bound to the class itself rather than to one object, written with the @classmethod decorator.
Last updated: 13 Oct, 2026 · Python 3.12
The methods so far acted on one object through self. Some data and some actions belong to the class as a whole, not to any single ticket, and that is what class variables, class methods and static methods are for.
base_price on a Car as a class variable and raises it with a @classmethod; the run below is that example. The rest of the page uses the course's Ticket and also covers @staticmethod, which this video does not.class Car:
base_price = 100000 # one value shared by every Car, set in the class body
def __init__(self, windows, doors, power):
self.windows = windows
self.doors = doors
self.power = power
@classmethod
def revise_base_price(cls, inflation):
# cls is the class, so this updates base_price for every Car at once
cls.base_price = cls.base_price + cls.base_price * inflation
car1 = Car(4, 5, 2000)
print(car1.base_price)
Car.revise_base_price(0.10) # raise it by 10% for next year
print(Car.base_price)100000 110000.0
Syntax:
class Name:
shared = 0 # a class variable
@classmethod
def make(cls, ...): # receives the class as cls
return cls(...)
@staticmethod
def helper(...): # receives neither self nor cls
return ...A class variable shared by every object
A variable set in the class body, outside __init__, is one value shared by every object. Here it counts how many tickets have been made:
class Ticket:
count = 0
def __init__(self, customer, text):
self.customer = customer
self.text = text
Ticket.count += 1a = Ticket("Asha", "I was charged twice")
b = Ticket("Ben", "My parcel has not arrived")
print(Ticket.count)
print(a.count, b.count)2 2 2
Ticket.count belongs to the class, so every object sees the same value. a.count and b.count read that one class variable, which is why both show 2 after two tickets are made.
An alternative constructor with @classmethod
A @classmethod receives the class as cls instead of an instance. It is the usual way to write a second constructor, such as building a ticket from a parsed JSON dictionary:
@classmethod
def from_dict(cls, data):
return cls(data["customer"], data["text"])raw = {"customer": "Chen", "text": "Can I get a refund?"}
ticket = Ticket.from_dict(raw)
print(ticket.customer, "/", ticket.text)Chen / Can I get a refund?
cls is Ticket, so cls(...) makes a Ticket the normal way. Writing cls rather than Ticket means a subclass that calls from_dict builds an object of the subclass, not the parent.
A helper with @staticmethod
A @staticmethod receives neither self nor cls. It is a plain function kept on the class because it belongs with it, such as a text cleaner the ticket code uses:
@staticmethod
def clean(text):
return text.strip().lower()print(Ticket.clean(" REFUND Please "))refund please
The three kinds together
class Ticket:
count = 0 # a class variable, shared by every Ticket
def __init__(self, customer, text):
self.customer = customer
self.text = text
Ticket.count += 1
@classmethod
def from_dict(cls, data):
return cls(data["customer"], data["text"])
@staticmethod
def clean(text):
return text.strip().lower()
a = Ticket("Asha", "I was charged twice")
b = Ticket.from_dict({"customer": "Ben", "text": " My PARCEL "})
print(Ticket.count)
print(b.customer, Ticket.clean(b.text))2 Ben my parcel
One class now holds a shared counter, a second constructor and a helper, each reaching for the class or for nothing rather than for one object.
Instance vs class vs static method
| Instance method | @classmethod | @staticmethod | |
|---|---|---|---|
| First argument | self | cls | none |
| Works on | One object | The class | Its arguments only |
| Typical use | Act on this ticket | A second constructor | A related helper |
Where these show up in AI code
- A second constructor, such as Pydantic's
Model.model_validate(data), which is a class method that builds an object from a dictionary. - Shared configuration or a registry kept on the class, read by every instance.
- Utility helpers grouped on the class they belong to, rather than loose functions.
__init__ with self.items = []; Common gotchas returns to this trap.Related
- Previous: Magic methods
- Next: dataclasses
- Reference: classmethod and staticmethod in the Python docs
- Add a class variable
categories = ["billing", "shipping", "other"]and a@staticmethodthat checks a category is in it. - Give
Ticketa second@classmethod,blank(cls), that makes a ticket with empty text. - Read
Ticket.countbefore and after making a ticket.
Little by little, you're building something great.