Lesson explanation
After this lesson, you will be able to:
self), a class (cls), or neither.@classmethod to work with class-level information or create objects.@staticmethod for a utility that belongs conceptually to a class.A regular instance method starts with self, the current object. You already used it to read and change the attributes created in __init__:
class Job:
def __init__(self, name):
self.name = name
def display_name(self):
return self.name.upper()A class method starts with cls and is marked with @classmethod. It receives the class automatically, whether you call it through the class or an instance. Class methods are useful for reading a shared setting or constructing an instance from a different input format.
A static method, marked with @staticmethod, does not receive self or cls automatically. Use it for a closely related calculation or validation that does not need an object's state.
These annotations use @... syntax, but you do not need general-purpose decorators yet. @classmethod and @staticmethod are the built-in forms you need in this lesson.
cls refers to the class, so the result uses its shared setting.
class Mailer:
default_sender = "robot@example.com"
@classmethod
def sender(cls):
return cls.default_sender
print(Mailer.sender())Output:
robot@example.comUnlike an instance method, this can be called without making a Mailer object.
A static method groups a utility with the type it relates to. It accepts only the parameters you write.
class PortRules:
@staticmethod
def is_allowed(port):
return 1 <= port <= 65535
print(PortRules.is_allowed(443))Output:
TrueThere is no self or cls in is_allowed because it uses only port.
A class method can offer another way to create a valid instance.
class Badge:
def __init__(self, title):
self.title = title
@classmethod
def from_text(cls, raw_title):
return cls(raw_title.strip())
print(Badge.from_text(" Operator ").title)Output:
OperatorUsing cls(...) constructs an instance of the class that receives the call.
A method using self returns information about the specific object.
class Subscription:
def __init__(self, plan, active):
self.plan = plan
self.active = active
def status(self):
if self.active:
return f"{self.plan}: active"
return f"{self.plan}: inactive"
print(Subscription("starter", False).status())Output:
starter: inactiveEach subscription can have different state, so an instance method is appropriate.
| Method | First parameter | Receives automatically | Common use |
|---|---|---|---|
| Instance method | self | Object | Read/update its attributes |
@classmethod | cls | Class | Shared settings, alternative constructors |
@staticmethod | Neither | Nothing | Related validation, normalization |
@classmethod and assuming cls is passed automatically.self even though the caller only supplies its explicit arguments.self.setting when the goal is to change a setting shared by the class.