[python] @staticmethod

gunny·2024년 7월 25일
0

Python

목록 보기
29/29

서론

저번에 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"
  • 위 코드에서 첫 번째 매개변수로 'self'를 가지고, 메소드가 호출되는 인스턴스 자신을 참조한다.
  • 인스턴스 메소드는 클래스의 상태(인스턴스 변수)나 다른 인스턴스 메소드에 접근할 수 있다.
  • 인스턴스의 상태에 따라 동작이 달라지는 경우인 즉, 각 인스턴스가 고유의 데이터를 가지고 있고 이 데이터를 기반으로 작업을 수행해야 할 때 사용한다.
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
  • 첫번째 매개변수로 'self'나 'cls'를 받지 않는다.
  • 클래스나 인스턴스의 상태와 관련이 없는 독립적인 작업을 수행하는데 적합하다.

위의 예시 코드 처럼 인스턴스 생성 없이 클래스 메소드를 호출하는 경우를 다른 코드로 본다면


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 
  • 첫 번째 매개변수로 'cls' 를 받아 클래스 변수와 클래스 메소드에 접근할 수 있다.
  • 클래스 메소드는 클래스 수주에서 동작하고, 특정 크래스의 상태나 동작을 조작할 수 있다.
  • 위 코드 처럼 클래스 변수에 접근하거나 클래스 전체에 적용할 작업을 수행할 때 사용하는데, 팩토리 메소드(factory method)나 클래스에 관련된 상태를 조작하는 데 유용하다.

장점으로는

  • 클래스 수준에서 동작해서 클래스 변수나 상태를 조작하고 객체를 생성하지 않아도 클래스 자체에 대한 작업을 수행할 수 있다.

결론

  • 인스턴스 메소드 self : 인스턴스의 상태에 접근하고, 인스턴스 별로 동작이 다를 수 있는 메소드에 사용한다. 객체의 데이터를 기반으로 동작할 때 필요하다.
  • 클래스 메소드 @classmethod : 클래스 변수나 클래스 전체의 상태를 조작할 때 사용한다. 클래스 수준의 작업이 필요할 때 유용하다
  • 정적 메소드 @staticmethod : 클래스와 인스턴스의 상태와 무관한 독립적인 작업을 사용할 때 사용한다.

즉, 각 메소드의 유형은 서로 다른 목적과 상황에 맞게 설계되어 있고 코드의 구조와 가독성을 개선하는데 중요한 역할을 한다.

기타

그러니까 내가 작업했던 서비스에서 클래스 수준에 대한 작업이 필요하지도 않고, 인스턴스 별로 동작이 다를 수 있는 메소드가 아니라 그냥 특정 유저 id에 해당하는 데이터만 긁어오고 따로 후작업이 없어 해당 데이터를 기반으로 동작하는 것도 아니기 떄문에, 정적 메소드를 사용해서 독립적으로 해당 데이터를 불러오는 작업만을 하기 떄문에 @staticmethod를 사용해서 클래스를 구현하는게 코드 구조와 가독성을 위해서 필요했던 것 같다.

다음에 클래스를 구현할 때, 해당 클래스를 사용하게 될 때 클래스 수준에서의 핸들링이 필요한지, 그 아래의 인스턴스 별로 동작이 다른 메소드인지, 아니면 독립적인 작업을 필요로하는 건지 생각하고 클래스를 구현해야겠다.

사실 기본 지식이 부족해서 무조건 클래스를 구현하면 인스턴스 메소드로 구현하는게 정석인줄 알아서, __init__에 넣을 것이 없으면 pass 하고 아래 메소드를 구현했었다. 잘 생각하자구 ~

profile
꿈꾸는 것도 개발처럼 깊게

0개의 댓글