Python Class Methods and Static Methods
1Python Class Methods: overview
A class method receives the class itself (cls) instead of one object, which makes it ideal for alternative constructors and class-level state, while a static method receives nothing automatically and is just a plain function filed inside the class.
Before this lesson: Python Classes and Objects, Python Class Attributes vs Instance Attributes
2Python Class Methods: diagram
3Python Class Methods: explained step by step
So far every method you have written starts with self, which means it works on one particular object. That covers most needs, but two situations keep coming up:
- You want a method that belongs to the class as a whole, such as a new way to create objects or an update to a class-level counter. At that moment there may be no object to call it on.
- You have a helper function that is clearly about the class but never touches any object's data.
Python has a kind of method for each: class methods and static methods. You create them with a decorator, a line starting with @ placed directly above the def, which tells Python to treat the method differently.
Three kinds of method
The diagram above compares them. The real difference is what Python passes in automatically as the first argument: the object (instance method), the class (class method), or nothing (static method). That decides what data each kind can reach.
Class methods and cls
Put @classmethod above a method and name its first parameter cls. Python then passes the class itself instead of an object. With cls you can read class attributes and, most usefully, create objects: cls(...) does the same as calling the class by name.
class Pizza:
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
@classmethod
def from_string(cls, text):
inches, toppings = text.split(":")
return cls(int(inches), toppings.split(","))
def describe(self):
return f"{self.inches}-inch pizza with {', '.join(self.toppings)}"
order = Pizza.from_string("12:ham,olives,corn")
print(order.describe())You call it on the class, Pizza.from_string(...), and no pizza has to exist yet. Inside, cls is Pizza, so cls(...) builds a new pizza. Writing cls instead of the literal class name keeps the method correct if the class is renamed or extended later.
Alternative constructors
A class gets only one __init__. Class methods fill the gap: each one is a named "door" into creating an object, usually called from_something. The caller picks the door that matches the data they have.
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, text): # build from text like "2024-12-25"
year, month, day = text.split("-")
return cls(int(year), int(month), int(day))
@classmethod
def new_year(cls, year): # build from fixed data: always 1 January
return cls(year, 1, 1)
def __str__(self):
return f"{self.day:02d}/{self.month:02d}/{self.year}"
print(Date(2025, 3, 14))
print(Date.from_string("2024-12-25"))
print(Date.new_year(2026))Every door ends in cls(...), so all objects are still set up by the same __init__. That keeps the rules for a valid object in one place.
Class methods and class-level state
Because cls is the class, cls.count = 0 changes the class attribute that every object shares. (Doing the same through self would only create an instance attribute that hides it, as you saw in the previous lesson.)
class Player:
count = 0
def __init__(self, name):
self.name = name
Player.count += 1
@classmethod
def how_many(cls):
return f"{cls.count} players created"
@classmethod
def reset_count(cls):
cls.count = 0
Player("Asha")
Player("Ben")
print(Player.how_many())
Player.reset_count()
print(Player.how_many())Static methods
Sometimes a function is closely related to a class but needs neither an object nor the class itself. @staticmethod stores such a function inside the class. Python passes no automatic first argument, so you write exactly the parameters you want. A static method is a plain function that happens to live in the class's namespace, which keeps related code together and ties the name to the class.
class Temperature:
@staticmethod
def celsius_to_fahrenheit(celsius):
return celsius * 9 / 5 + 32
print(Temperature.celsius_to_fahrenheit(100))
reading = Temperature()
print(reading.celsius_to_fahrenheit(0))Calling all three kinds
Each kind can be called through the class or through an object, but they do not behave identically. An instance method called through the class needs the object handed over by hand. Class and static methods work the same either way.
class Cafe:
drinks_sold = 0
def __init__(self, name):
self.name = name
def sell(self): # instance method: needs one cafe
Cafe.drinks_sold += 1
return f"{self.name} sold a drink"
@classmethod
def total_sold(cls): # class method: receives the class
return cls.drinks_sold
@staticmethod
def is_open(hour): # static method: receives nothing extra
return 8 <= hour < 18
harbor = Cafe("Harbor Cafe")
print(harbor.sell())
print(Cafe.sell(harbor)) # through the class: pass the object yourself
print(Cafe.total_sold(), harbor.total_sold())
print(Cafe.is_open(9), harbor.is_open(20))Cafe.sell(harbor) is exactly what harbor.sell() does behind the scenes.
Which kind do I need?
- It uses the data of one object (
self.something)? Write an instance method. - It needs the class, either to create objects or to read and change class attributes, but not one particular object? Write a class method.
- It needs neither? It might be a static method, but read the next section first.
When not to use a static method
In Python a function does not have to live inside a class. If it needs neither an object nor the class, a plain module-level function is often the simplest choice:
def celsius_to_fahrenheit(celsius):
return celsius * 9 / 5 + 32
Choose a static method when the function is really part of the class's idea and you want it found next to the related code, like Pizza.inches_to_cm(12). A class that holds nothing but static methods and is never instantiated is just a module in disguise.
Quick reference: Python Class Methods
- Python @staticmethod vs @classmethod: What Is the Difference? — A `@classmethod` receives the **class itself** as its first argument (`cls`) and can create or configure inst…
4Python Class Methods: syntax
class ClassName:
shared = 0 # class attribute
def __init__(self, a):
self.a = a
def instance_method(self): # first parameter: the object
return self.a
@classmethod
def from_text(cls, text): # first parameter: the class
return cls(int(text)) # build and return a new object
@staticmethod
def helper(x): # no self, no cls
return x * 2
obj = ClassName.from_text("5") # class method: call it on the class
obj.instance_method() # instance method: call it on an object
ClassName.helper(4) # static method: through the class ...
obj.helper(4) # ... or through an object
5Python Class Methods: run the example
Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.
class Pizza:
made = 0
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
Pizza.made += 1
@classmethod
def from_string(cls, text):
inches, toppings = text.split(":")
return cls(int(inches), toppings.split(","))
@staticmethod
def inches_to_cm(inches):
return round(inches * 2.54, 1)
def __str__(self):
return f"{self.inches}-inch pizza with {', '.join(self.toppings)}"
order = Pizza.from_string("12:ham,olives")
print(order)
print(Pizza.inches_to_cm(order.inches), "cm")
print("Pizzas made:", Pizza.made)Expected output12-inch pizza with ham, olives
30.5 cm
Pizzas made: 1
7Python Class Methods: how the example works
Hover or tap a step to highlight its lines in the example above.
- Line 1-2
madeis a class attribute: one shared counter for the wholePizzaclass. - Line 4-7
__init__is a normal instance method. It stores the size and toppings onselfand adds one to the shared counter through the class name. - Line 9-12
@classmethodmakesfrom_stringreceive the class ascls. It splits"12:ham,olives"into the size and the toppings, converts the size to a number, and returnscls(...), so the new pizza is built by__init__like any other. - Line 14-16
@staticmethodmakesinches_to_cma plain function stored in the class. It gets only the argument you pass and cannot seeselforcls. - Line 18-19
__str__is an instance method that describes one pizza. It usesself.inchesandself.toppings. - Line 21
Pizza.from_string(...)is called on the class because no pizza exists yet. It returns a newPizzaobject, which is stored inorder. - Line 22
print(order)calls__str__and shows12-inch pizza with ham, olives. - Line 23The static method is also called on the class. 12 inches is 30.48 cm, rounded to 30.5.
- Line 24Only one pizza was built, through
from_stringand then__init__, so the counter reads 1.
8Python Class Methods: common mistakes
Forgetting @classmethod
✗ Wrong
class Pizza:
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
def from_string(cls, text):
inches, toppings = text.split(":")
return cls(int(inches), toppings.split(","))
order = Pizza.from_string("12:ham,olives")✓ Right
class Pizza:
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
@classmethod
def from_string(cls, text):
inches, toppings = text.split(":")
return cls(int(inches), toppings.split(","))
order = Pizza.from_string("12:ham,olives")
print(order.inches, order.toppings)Without the decorator, from_string is a plain function: the string you pass lands in cls and nothing is left for text. Add @classmethod above the def so Python passes the class automatically.
A helper without @staticmethod called on an object
✗ Wrong
class Converter:
def km_to_miles(km):
return km * 0.621371
trip = Converter()
print(trip.km_to_miles(10))✓ Right
class Converter:
@staticmethod
def km_to_miles(km):
return km * 0.621371
trip = Converter()
print(trip.km_to_miles(10))Called on an object, a normal method receives that object as an extra first argument. Mark the helper with @staticmethod so Python passes nothing extra.
Reading instance data inside a class method
✗ Wrong
class Player:
def __init__(self, name):
self.name = name
@classmethod
def greet(cls):
return f"Hello, {cls.name}"
print(Player("Asha").greet())✓ Right
class Player:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}"
print(Player("Asha").greet())A class method receives the class, and name belongs to individual objects, so the class has no name. If the method needs one player's data, make it a normal instance method that uses self.
An alternative constructor that forgets to return
✗ Wrong
class Pizza:
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
@classmethod
def from_string(cls, text):
inches, toppings = text.split(":")
cls(int(inches), toppings.split(","))
order = Pizza.from_string("12:ham,olives")
print(order.inches)✓ Right
class Pizza:
def __init__(self, inches, toppings):
self.inches = inches
self.toppings = toppings
@classmethod
def from_string(cls, text):
inches, toppings = text.split(":")
return cls(int(inches), toppings.split(","))
order = Pizza.from_string("12:ham,olives")
print(order.inches)The method built a pizza but threw it away, so the call returned None. A factory method must return the object it creates.
9Python Class Methods: exercises
Write your answer, then press Check. The checks run in your browser.
1. A square factory
Write code Easy ✓ CompletedAdd a class method square(cls, side) to Rectangle. It must return a new Rectangle whose width and height are both side. Build the object with cls(...).
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# add a class method square(cls, side) here
print(Rectangle(3, 4).area())
@classmethod above def square(cls, side): and return cls(side, side).class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
@classmethod
def square(cls, side):
return cls(side, side)
print(Rectangle(3, 4).area())
print(Rectangle.square(5).area())
2. Predict the three method kinds
Predict the output Medium ✓ CompletedThis class uses an instance method, a class method and a static method. Type exactly what the program prints.
class Gym:
members = 0
def __init__(self, name):
self.name = name
Gym.members += 1
@classmethod
def count(cls):
return cls.members
@staticmethod
def hours():
return "6am-10pm"
def welcome(self):
return f"Welcome, {self.name}! ({Gym.count()} members)"
a = Gym("Asha")
b = Gym("Ben")
print(a.welcome())
print(Gym.count(), b.count(), Gym.hours())
print(Gym.welcome(b))
print, so the shared counter is already 2. Gym.welcome(b) is the same as b.welcome().Welcome, Asha! (2 members)
2 2 6am-10pm
Welcome, Ben! (2 members)
2 more exercises → 6 more examples
Questions learners ask
What is the difference between @classmethod and @staticmethod?
A class method receives the class as its first argument (cls), so it can read and change class attributes and create new objects with cls(...). A static method receives no automatic argument at all; it is an ordinary function stored inside the class. Neither one receives an object (self).
How do I write more than one constructor in Python?
A class can have only one init, so add alternative constructors as class methods, usually named from_something, such as Pizza.from_string(...) or Date.from_string(...). Each one prepares the data and ends with return cls(...), so the object is still built by init.
Should I use a static method or a normal function?
Python does not force you to put functions inside classes. If the function needs neither self nor cls, a plain module-level function is usually simpler. Use a static method only when the function is clearly part of the class's idea and you want it kept next to the related code, for example Pizza.inches_to_cm().
Further reading
10Next lesson
Up nextPython Encapsulation: Public, Protected and PrivateEncapsulation means keeping an object's data behind a small set of public methods that check every change, so the objec…Related:
Python FunctionsPython Class Attributes vs Instance AttributesPython Dunder (Magic) Methods
← Python Class Attributes vs Instance Attributes · All Object-Oriented Python lessons · Practise in the IDE