파이썬 @staticmethod vs @classmethod

SOCICAL·2025년 2월 6일
0
# 최근 수정 날짜: 25.02.07

"우리는 @ 가 붙은 것을 데코레이터라고 부른다. 즉 데코레이터 기호 라고 부른다."

Python에서 클래스 내부의 메서드는 크게 3가지로 나뉜다.
1. 인스턴스 메서드 (Instance Method)
2. 정적 메서드 (Static Method, @staticmethod)
3. 클래스 메서드 (Class Method, @classmethod)

@staticmethod@classmethod의 차이점을 정리하고, 언제 어떤 메서드를 사용해야 하는지 살펴보겠다.


# 인스턴스 메서드 (self 사용)

class Example:
    def instance_method(self):
        print(f"Called from instance: {self}")

obj = Example()
obj.instance_method()  # Called from instance: <__main__.Example object at 0x...>

✅ self를 사용하여 인스턴스 변수에 접근 가능
✅ 객체를 생성한 후 obj.method() 형태로 호출해야 함


# 정적 메서드 (@staticmethod)

  • 정적 메서드는 클래스나 인스턴스의 상태와 관계없이 동작하는 독립적인 메서드이다.
class Example:
    @staticmethod
    def static_method():
        print("Hello from static method!")

# 클래스에서 바로 호출 가능
Example.static_method()  # Hello from static method!

✅ self와 cls를 받지 않음
✅ 클래스나 인스턴스 변수에 접근하지 않는 독립적인 기능을 정의할 때 사용
✅ 클래스 이름으로 직접 호출 가능 (Class.method())

📌 정적 메서드가 필요한 경우

  • 단순한 유틸리티 함수 (ex: 수학 계산, 날짜 변환 등)
  • 클래스 내부에 있지만, 클래스 변수나 인스턴스 변수와 관계없는 기능이 필요할 때
import datetime

class DateUtils:
    @staticmethod
    def is_weekend(date):
        return date.weekday() >= 5  # 5: 토요일, 6: 일요일

print(DateUtils.is_weekend(datetime.date(2025, 2, 8)))  # True (토요일)

# 클래스 메서드 (@classmethod)

  • 클래스 메서드는 클래스 변수(cls)를 다루는 메서드이다.
class Example:
    count = 0  # 클래스 변수

    @classmethod
    def increase_count(cls):
        cls.count += 1  # 클래스 변수 변경
        print(f"Count is now {cls.count}")

Example.increase_count()  # Count is now 1
Example.increase_count()  # Count is now 2

✅ cls를 사용하여 클래스 변수에 접근 가능
✅ 클래스 변수(모든 객체가 공유하는 변수)를 수정할 때 유용
✅ 클래스 이름으로 직접 호출 가능 (Class.method())

📌 클래스 메서드가 필요한 경우

  • 클래스 변수를 읽거나 수정할 때
  • 객체를 생성하는 대체 생성자를 만들 때 (== 기본 생성자(init) 를 직접 호출하지 않고도 새로운 객체(인스턴스)를 생성하는 클래스 메서드...-.-)
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def from_birth_year(cls, name, birth_year):
        return cls(name, 2025 - birth_year)  # cls()를 사용해 인스턴스 생성

p1 = Person.from_birth_year("Alice", 1995)
print(p1.name, p1.age)  # Alice 30

📌 클래스 메서드는 cls(name, age)를 호출하여 새로운 인스턴스를 생성할 수 있음.
📌 Person.from_birth_year("Alice", 1995) → Person("Alice", 30) 과 동일

# 왜 "도대체 대체 생성자가 뭐야??? 왜 사용하는거지,,,

  • 기본적으로 객체를 만들려면 init()을 사용해야 한다.
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p1 = Person("Alice", 30)  # 직접 생성
print(p1.name, p1.age)  # Alice 30

✅ 보통 이렇게 init()을 사용해 객체를 생성함.

근데

✅ "대체 생성자"를 사용한 객체 생성

  • 하지만, 다른 방식으로 객체를 생성하고 싶다면? 예를 들어, 나이가 아닌 출생 연도를 입력하면 자동으로 나이를 계산하는 방식을 원한다고 하자.
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def from_birth_year(cls, name, birth_year):
        return cls(name, 2025 - birth_year)  # cls()를 사용해 객체 생성

p1 = Person.from_birth_year("Alice", 1995)
print(p1.name, p1.age)  # Alice 30

✅ from_birth_year()라는 "대체 생성자"를 만들었음.
✅ 이제 Person("Alice", 30) 대신 Person.from_birth_year("Alice", 1995)처럼 객체를 만들 수 있음!


🎯 정리

  1. @staticmethod
    ✔ self, cls를 받지 않음 → 독립적인 기능을 수행하는 메서드
    ✔ 클래스 내부에 정의되지만 클래스나 인스턴스 변수와 관계없는 함수
    ✔ 유틸리티 함수로 활용 (ex: 날짜 변환, 수학 연산)

  2. @classmethod
    ✔ cls를 받음 → 클래스 변수를 다룰 수 있음
    ✔ 클래스 변수를 읽거나 수정하는 메서드
    ✔ 대체 생성자로 활용 (ex: from_birth_year)

0개의 댓글