Class Methods¶
Class methods receive the class itself as the first argument, enabling operations on class-level data and alternative constructors.
What are Class Methods¶
1. Decorated with @classmethod¶
class Student:
count = 0
@classmethod
def increment_count(cls):
cls.count += 1
2. Receive cls¶
First parameter is the class, not instance.
3. Operate on Class¶
Modify or access class-level attributes.
Defining Class Methods¶
1. Basic Syntax¶
class MyClass:
class_var = 0
@classmethod
def class_method(cls):
cls.class_var += 1
2. Call via Class¶
MyClass.class_method()
print(MyClass.class_var) # 1
3. Call via Instance¶
obj = MyClass()
obj.class_method() # Works but not idiomatic
Class Method Use Cases¶
1. Modify Class Attributes¶
class Student:
university = 'Yonsei'
@classmethod
def change_university(cls, new_name):
cls.university = new_name
Student.change_university('YonHei')
2. Track All Instances¶
class Student:
students_list = []
mandatory = ['Chapel']
@classmethod
def add_mandatory(cls, course):
if course not in cls.mandatory:
cls.mandatory.append(course)
for student in cls.students_list:
student.subject.append(course)
3. Global Configuration¶
class Logger:
enable_debug = False
@classmethod
def set_debug(cls):
cls.enable_debug = True
Alternative Constructors¶
1. Factory Pattern¶
from datetime import date
class Person:
def __init__(self, name, birth_year):
self.name = name
self.birth_year = birth_year
@classmethod
def from_age(cls, name, age):
current_year = date.today().year
return cls(name, current_year - age)
p = Person.from_age("Alice", 30)
2. Parse Data¶
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def from_string(cls, point_str):
x, y = map(float, point_str.split(','))
return cls(x, y)
p = Point.from_string("3.5,2.1")
3. Multiple Formats¶
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_str):
y, m, d = map(int, date_str.split('-'))
return cls(y, m, d)
@classmethod
def today(cls):
import datetime
today = datetime.date.today()
return cls(today.year, today.month, today.day)
Student Example¶
1. Class Setup¶
class Student:
students_list = []
mandatory = ['Chapel']
def __init__(self, name, major, courses):
self.name = name
self.major = major
self.courses = courses
Student.students_list.append(self)
2. Add Mandatory Course¶
@classmethod
def add_mandatory(cls, course):
if course not in cls.mandatory:
cls.mandatory.append(course)
for student in cls.students_list:
student.courses.append(course)
3. Drop Mandatory Course¶
@classmethod
def drop_mandatory(cls, course):
if course in cls.mandatory:
cls.mandatory.remove(course)
for student in cls.students_list:
if course in student.courses:
student.courses.remove(course)
cls vs self¶
1. cls Parameter¶
@classmethod
def class_method(cls):
# cls refers to the class
cls.class_var = 10
2. self Parameter¶
def instance_method(self):
# self refers to the instance
self.instance_var = 10
3. Different Scopes¶
Class methods operate on class, instance methods on instances.
Inheritance Behavior¶
1. Inherited Methods¶
class Parent:
count = 0
@classmethod
def increment(cls):
cls.count += 1
class Child(Parent):
pass
Child.increment()
print(Child.count) # 1
print(Parent.count) # 0
2. cls is Dynamic¶
cls refers to the calling class.
3. Polymorphic Behavior¶
class Shape:
@classmethod
def create_default(cls):
return cls() # Creates instance of calling class
class Circle(Shape):
pass
c = Circle.create_default() # Creates Circle
When to Use¶
1. Modify Class State¶
@classmethod
def reset_counter(cls):
cls.counter = 0
2. Alternative Constructors¶
@classmethod
def from_json(cls, json_str):
data = json.loads(json_str)
return cls(**data)
3. Affect All Instances¶
@classmethod
def enable_feature_for_all(cls):
cls.feature_enabled = True
Common Patterns¶
1. Configuration¶
class Config:
debug_mode = False
@classmethod
def enable_debug(cls):
cls.debug_mode = True
@classmethod
def disable_debug(cls):
cls.debug_mode = False
2. Registry¶
class Plugin:
_plugins = []
@classmethod
def register(cls, plugin):
cls._plugins.append(plugin)
@classmethod
def get_plugins(cls):
return cls._plugins[:]
3. Singleton Pattern¶
class Singleton:
_instance = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
Class vs Static¶
1. Class Method¶
@classmethod
def class_method(cls, param):
# Has access to cls
cls.class_var = param
2. Static Method¶
@staticmethod
def static_method(param):
# No access to cls or self
return param * 2
3. Choose Based on Need¶
Use class method if you need class reference.
Key Takeaways¶
- Class methods receive
clsas first parameter. - Use
@classmethoddecorator. - Modify class-level attributes.
- Create alternative constructors.
- Affect all instances of the class.