저번에 python의 @classmethod를 보고 classmethod에 대한 글을 포스팅 한 바 있다.
[python classmethod]
https://velog.io/@heyggun/python-classmethod
그 때 이해했다고 생각했는데, 이번에 서비스에 들어갈 클래스를 구현하면서 pr을 날렸는데
""" 모든 initialize 메소드가 pass라서 굳이 instance가 필요 없어 보입니다. @staticmethod를 사용해도 좋을 것 같습니다."""
라는 comment를 받았다.
그렇다! 완전히 이해를 못한 것이다.
그래서 이번에 @staticmethod와 @classmethod 그리고 인스턴스 메소드의 차이를 다시 한 번 정리해보려고 한다.
클래스의 인스턴스를 생성하지 않고, 클래스의 메소드를 사용하는 것은 객체 지향 프로그래밍에서 특정 메소드가 클래스의 인스턴스와 관계없이 독립적으로 작동할 수 있음을 의미한다. 이를 정적 메소드(@staticmethod
) 로 구현할 수 있다.
일단 먼저 인스턴스 메소드
와 정적 메소드
를 살펴보자
인스턴스 메소드
class MyClass:
def __init__(self, value):
self.value =value
def instance_method(self):
return f"Value is {self.value}"
obj = MyClass(10)
print(obj.instance_method()) # "Value is 10"
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"My name is {self.name} and I am {self.age} years old."
person = Person("Alice", 30)
print(person.introduce()) # "My name is Alice and I am 30 years old."
정적 메소드
class MyClass:
@staticmethod
def static_method(x,y):
return x+y
print(MyClass.static_method(5,3)) # 8
위의 예시 코드 처럼 인스턴스 생성 없이 클래스 메소드를 호출하는 경우를 다른 코드로 본다면
class MathUtilities:
@saticmethod
def add(a, b):
return a+b
result = MathUtilities.add(5,3)
print(result) # 8
이러한 정적 메소드 사용의 장점은
(1) 단순화된 코드 : 클래스 인스턴스를 생성할 필요가 없어 코드가 간단해짐. 유틸리티 함수나 공통 기능을 제공하는 메소드에 유용
(2) 명확한 의도 : 정적 메소드로 선언하면 해당 메소드가 인스턴스 상태에 의존하지 않고 독립적으로 작동함을 명확히 알릴 수 있따
(3) 성능 고려: 인스턴스를 생성하지 않아 메모리와 성능 측면에서 이점이 있다. 메소드 호출이 간편하고 빠르다.
클래스 메소드(@classmethod)
class Person:
population = 0
def __init__(self, name):
self.name = name
Person.population += 1
@classmethod
def get_population(cls):
return cls.population
person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_population()) # 2
장점으로는
self
: 인스턴스의 상태에 접근하고, 인스턴스 별로 동작이 다를 수 있는 메소드에 사용한다. 객체의 데이터를 기반으로 동작할 때 필요하다.@classmethod
: 클래스 변수나 클래스 전체의 상태를 조작할 때 사용한다. 클래스 수준의 작업이 필요할 때 유용하다@staticmethod
: 클래스와 인스턴스의 상태와 무관한 독립적인 작업을 사용할 때 사용한다.즉, 각 메소드의 유형은 서로 다른 목적과 상황에 맞게 설계되어 있고 코드의 구조와 가독성을 개선하는데 중요한 역할을 한다.
그러니까 내가 작업했던 서비스에서 클래스 수준에 대한 작업이 필요하지도 않고, 인스턴스 별로 동작이 다를 수 있는 메소드가 아니라 그냥 특정 유저 id에 해당하는 데이터만 긁어오고 따로 후작업이 없어 해당 데이터를 기반으로 동작하는 것도 아니기 떄문에, 정적 메소드를 사용해서 독립적으로 해당 데이터를 불러오는 작업만을 하기 떄문에 @staticmethod를 사용해서 클래스를 구현하는게 코드 구조와 가독성을 위해서 필요했던 것 같다.
다음에 클래스를 구현할 때, 해당 클래스를 사용하게 될 때 클래스 수준에서의 핸들링이 필요한지, 그 아래의 인스턴스 별로 동작이 다른 메소드인지, 아니면 독립적인 작업을 필요로하는 건지 생각하고 클래스를 구현해야겠다.
사실 기본 지식이 부족해서 무조건 클래스를 구현하면 인스턴스 메소드로 구현하는게 정석인줄 알아서, __init__
에 넣을 것이 없으면 pass 하고 아래 메소드를 구현했었다. 잘 생각하자구 ~