cls
를 받는데,cls
인자는 해당 클래스 자체를 나타낸다.클래스 메소드가 인스턴스에 의존하지 않고 클래스 자체에 대한 작업을 수행한다?
클래스 메소드가 인스턴스에 의존하지 않고, 클래스 자체에 대한 작업을 수행한다는 의미는 해당 메소드가 특정한 인스턴스 속성에 접근하거나 수정하지 않고 대신 클래스 자체의 속성이나 기능을 다룬다는 것을 의미한다.
예를 들어 보자면 "Person" 클래스를 생성했다고 했을 때,
이 클래스는 각각의 인스턴스가 사람의 이름과 나이를 나타내는 속성을 가지고 있다.
이 클래스에 클래스메소드(classmethod)를 추가해서 인스턴스를 생성할 때 일반적인 사람들의 나이를 기준으로 특정 조치를 취하는 기능을 구현해본다.
class Person:
common_age = 30
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def is_common_age(cls, person_age):
return person_age == cls.common_age
person1 = Person('Person1', 25)
person2 = Person('Person2', 30)
print(Person.is_common_age(person1.age)) # False
print(Person.is_common_age(person2.age)) # True
위와 같이 'is_comon_age' 메소드를 클래스 메소드(classmetbod)로 정의했는데, 이 메소드는 특정 사람의 나이를 입력으로 받고, 그 나이가 'Person' 클래스의 'common_age' 클래스 변수와 같은지 여부를 반환한다.
이 클래스 메소드는 특정 인스턴스 속성에 의존하지 않고, 대신 클래스 자체의 속성인 'common_age'에만 의존한다.
따라서 이 메소드는 클래스 레벨에서 호출될 때 일반적인 연령을 확인하는 기능을 수행하고, 이것이 "클래스 메소드가 인스턴스에 의존하지 않고 클래스 자체에 대한 작업을 수생한다"라는 의미를 가진다.
다른 예시로 FastAPI에서 클래스 메소드를 사용하는 예시를 살펴보자.
아래는 간단한 ToDo 리스트 애플리케이션이다.
여기서 클래스 메소드를 사용해서 모든 ToDo 항목을 가져오는 메소드를 추가한다.
app = FastAPI()
class Todo(BaseModel):
id : int
title : str
completed : bool
# 임시 데이터 베이스 역할을 할 리스트
todos = []
class TodoManager:
@classmethod
def get_all_todos(cls) -> List[Todo]:
return todos
# ToDo 목록을 가져오는 엔드포인트
@app.get("/todos/", response_model=List[Todo])
def read_todos():
return TodoManager.get_all_todos()
위 코드에서 TodoManager
클래스에 get_all_todos
라는 클래스 메소드를 추가했다. 이 메소드는 todos
리스트에 있는 모든 ToDo 항목을 반환한다.
TodoManager
클래스의 클래스 메소드를 사용해 ToDo 목록을 관리할 수 있다. 이러한 설계는 특정 인스턴스에 의존하지 않고 클래스 자체에 대한 작업을 수행하는 것이고, 이를 통해서 코드를 더 깔끔하게 유지할 수 있다.
즉, 클래스메소드를 사용함으로써 메소드가 클래스 레벨에서 작동하고 클래스 변수에 쉽게 접근할 수 있게 된다.