An instance method binds an instance, a classmethod binds the selected class, and a staticmethod receives neither implicitly.
Python staticmethod and classmethod: choose the bound receiver
Operation contract
The receipt class uses a classmethod constructor so a subclass receives its own class as the constructor target. A static validator operates only on its explicit quantity argument. An instance method calculates cost from that receipt’s state. These three responsibilities need different receivers rather than one universal utility method.
Failure and ownership boundary
A classmethod constructor can violate a subclass invariant if the base assumes every subclass accepts the same constructor signature. Staticmethod does not restrict access to global state or guarantee purity. Binding behavior comes from descriptors, so assigning functions and reading them through an instance is not always equivalent to reading the class dictionary directly. Python descriptors: field validation and attribute precedence and Python super and method resolution: cooperate across mixins explain those mechanics.
Working program
class Receipt:
def __init__(self, quantity):
self.quantity = self.validate_quantity(quantity)
@staticmethod
def validate_quantity(quantity):
if type(quantity) is not int or not 1 <= quantity <= 20:
raise ValueError("quantity rejected")
return quantity
@classmethod
def from_quantity(cls, quantity):
return cls(quantity)
def amount(self, unit_minor):
return self.quantity * unit_minor
class ExpressReceipt(Receipt):
pass
receipt = ExpressReceipt.from_quantity(3)
print(type(receipt).__name__)
print(receipt.amount(125))
print(Receipt.validate_quantity(2))Output
ExpressReceipt
375
2Costs and limits
Receiver binding has small bookkeeping cost relative to the method body. The fixture’s validation is bounded; constructing a record retains its fields. It does not claim that static methods make an application faster than free functions.
Common Mistakes
- A classmethod constructor receives the subclass when called on it.
- Staticmethod supplies no purity or thread-safety guarantee.
Connected lessons
Python classes: keep instance state separate from class state, Python descriptors: field validation and attribute precedence, Python super and method resolution: cooperate across mixins.
