Python

[Python] 파이썬 classmethod와 staticmethod 차이

비아 VIA 2023. 3. 12. 22:32

회사 코드를 보면 종종 @classmethod, @staticmethod 를 사용하는데 정확히 어떻게 다른지 설명해보려면 헷갈릴 때가 있어서 정리해보려고 한다.

1. Instance Method

우선 클래스메서드와 정적 메서드를 살펴보기 전에 인스턴스 메서드를 살펴보자. 클래스 내부에서 정의되는 메소드 중 가장 일반적인 형태는 인스턴스 메소드다. 인스턴스 메소드는 클래스를 통해 생성된 객체(인스턴스)에서 호출된다.

인스턴스 메소드는 첫 번째 매개변수로 self를 받아 인스턴스 변수에 접근할 수 있다. self는 인스턴스 자신을 나타내는 파라미터이며, 인스턴스 메소드를 호출할 때 인스턴스를 전달해야 한다.

class Cat:
    def __init__(self, name, age, color):
        self.name = name
        self.age = age
        self.color = color

    def meow(self):
        print(f"{self.name}이(가) 야옹야옹")

    def info(self):
        print(f"이름: {self.name}")
        print(f"나이: {self.age}살")
        print(f"색상: {self.color}")
  • 위 코드에서 Cat 클래스는 고양이를 나타내며, 이름(name), 나이(age), 색상(color)을 속성으로 갖는다.
  • __init__ 메소드는 인스턴스가 생성될 때 호출되며, name, age, color를 초기화한다.
  • meow 메소드는 인스턴스가 야옹하는 소리를 출력하는 메소드이며, info 메소드는 고양이의 정보를 출력하는 메소드이다.
cat1 = Cat("나비", 2, "검정색")
cat2 = Cat("체다", 3, "노랑색")
  • 위 코드에서 cat1과 cat2는 Cat 클래스에서 생성된 인스턴스다.
  • name, age, color 속성은 각각 나비, 2, 검정색, 체다, 3, 노랑색으로 초기화된다.
cat1.meow()  # 출력: 나비이(가) 야옹야용!
cat2.info()  
# 출력:
# 이름: 체다
# 나이: 3살
# 색상: 노랑색
  • 위 코드에서 cat1 인스턴스에서 meow 메소드를 호출하면 나비이(가) 야옹야옹이 출력된다.
  • cat2 인스턴스에서 info 메소드를 호출하면 체다의 정보가 출력된다.
  • 이렇게 인스턴스 메소드를 사용하여 인스턴스의 특정 행동이나 정보를 가져올 수 있다.

 

2. 클래스 메소드 & 정적 메소드

class Cat:
    species = "코숏"

    def __init__(self, name, age, color):
        self.name = name
        self.age = age
        self.color = color

    @classmethod
    def from_birth_year(cls, name, birth_year, color):
        age = datetime.date.today().year - birth_year
        return cls(name, age, color)

    @staticmethod
    def meow():
        print("야옹야옹")
  • 위 코드에서 Cat 클래스는 고양이를 나타내며, species, name, age, color를 속성으로 갖는다. 
  • __init__ 메소드는 인스턴스가 생성될 때 호출되며, name, age, color를 초기화한다. 
  • from_birth_year 메소드는 클래스 메소드다. 클래스 메소드는 @classmethod 데코레이터를 사용하여 정의된다. 
  • 클래스 메소드는 첫 번째 인자로 cls를 받으며, 인스턴스가 아닌 클래스 자체가 첫 번째 인자로 전달된다. 
  • 인스턴스 메서드와 달리 인스턴스 속성에 접근하거나 다른 인스턴스 메서드를 호출하는 것은 불가능하다
  • 이때, 클래스 메소드는 클래스 변수를 조작하거나, 새로운 인스턴스를 생성할 수 있다.
cat1 = Cat.from_birth_year("삼색이", 2019, "삼색")
print(cat1.age)  # 출력: 4
  • 위 코드에서 from_birth_year 클래스 메소드를 호출하여 출생 연도로부터 고양이의 나이를 계산하고, Cat 클래스의 인스턴스를 생성한다.
  • 이때, 클래스 메소드는 클래스 자체에 대해 작업을 수행하므로, 클래스 변수인 species를 참조할 수 있다. 또한, cls 인자를 사용하여 Cat 클래스의 인스턴스를 생성할 수 있다.
Cat.meow()   # 출력: 야옹야옹
  • 반면에 meow는 정적 메소드다. 정적 메소드는 @staticmethod 데코레이터를 사용하여 정의된다. 정적 메소드는 클래스에서 직접 호출되며, 첫 번째 인자로 self를 받지 않는다. 첫번째 매개 변수가 할당되지 않는 것이다. 이런 이유로 정적 메소드는 클래스와 관련된 유틸리티 함수를 작성할 때 자주 사용된다.
  • 정적 메소드는 클래스나 인스턴스와 관련된 작업을 수행하지 않으므로, 클래스 또는 인스턴스에 바인딩되지 않는다. 즉, 정적 메소드는 클래스 내부의 데이터에 접근할 수 없다.
  • 정적 메서드는 인스턴스 속성, 인스턴스 메서드가 필요 없을 때 사용하며 메서드의 실행이 외부 상태에 영향을 끼치지 않는 순수 함수(pure function)을 만들 때 사용한다
  • 순수 함수는 부수효과(side effect)가 없고 입력 값이 같으면 언제나 같은 출력 값을 반환한다

+ 관련 기초: 클래스란?

  • 클래스(class)는 객체를 생성하기 위한 일종의 틀이다(붕어빵 만드는 틀을 생각하자!)
  • 클래스는 객체(Object)의 속성(attribute)과 행위(behavior)를 정의하는데 사용된다.
  • 생성된 객체는 클래스에서 정의된 속성과 메소드를 가지게 된다. 
  • 클래스로부터 생성된 객체를 인스턴스(instance)라고 부른다.

 

참고하면 좋은 링크

https://youtu.be/SXApHXsDe8I

https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod

 

Difference between @staticmethod and @classmethod

What is the difference between a method decorated with @staticmethod and one decorated with @classmethod?

stackoverflow.com

https://medium.com/school-of-code/classmethod-vs-staticmethod-in-python-8fe63efb1797

 

@classmethod vs. @staticmethod in Python

Something that unavoidably ends up coming up when learning Python is this issue of classmethods and staticmethods, especially for students…

medium.com

https://www.daleseo.com/python-class-methods-vs-static-methods/

 

[파이썬] 정적(static) 메서드와 클래스(class) 메서드

Engineering Blog by Dale Seo

www.daleseo.com