@staticmethod?
간단히 살펴보는 정적 메소드
staticmethod, 그러니까 정적 메소드는 클래스나 인스턴스의 변수와 상관없이 현재 전달한 변수만 바탕으로 작동한다.
- 그러니까 그냥 클래스 밖에 있는 함수를 가져다 쓰는 것과 마찬가지이며, 실제로 그렇게 해도 된다.
- 하지만 그 함수가 클래스와 의미적으로 연결이 깊다면 정적 메소드를 이용할 수 있다.
- 그런데
@staticmethod를 decorator(데코레이터)라고 부르길래 무엇이고, 또 다른 데코레이터가 있는 지 찾아보았다.
decorator(데코레이터란)?
- Python에서 @ 기호를 사용하여 함수나 메서드 위에 붙이면 자동으로 해당 데코레이터 함수가 실행된다.
- 클래스에서 사용되는 3가지 데코레이터
@staticmethod, classmethod, property와 특수 메서드에 대해 살펴보자.
- 아래는
decorator 사용 예시이다.
def decorator(func):
def wrapper():
print("함수 실행 전")
func()
print("함수 실행 후")
return wrapper
@decorator
def say_hello():
print("Hello!")
say_hello()
클래스와 인스턴스
- 아래 내용들을 이해하려면 우선 클래스와 인스턴스의 차이를 알아야한다.
- 클래스는 설계도, 인스턴스는 실물이라고 생각할 수 있다.
car라는 클래스가 있다면, 아반떼, 소나타 같은 인스턴스를 만들 수 있는 것이다.
- 이때 인스턴스 각각 독립적으로 가지고 있는 변수도 있고, 클래스가 갖고 있는 변수도 있다.
@staticmethod, @classmethod, @property
- 위 3가지 메서드를 사용하는 예시와 간단한 비교, 요약이다.
class Animal:
species = "Unknown"
def __init__(self, name, age):
self.name = name
self.age = age
def instance_method(self):
"""인스턴스 메서드: 인스턴스 변수(self)를 사용"""
return f"{self.name} is {self.age} years old."
@classmethod
def class_method(cls):
"""클래스 메서드: 클래스 변수(cls)를 사용"""
return f"This animal belongs to the species: {cls.species}"
@staticmethod
def static_method():
"""정적 메서드: 인스턴스나 클래스와 관련 없이 독립적 기능 수행"""
return "Animals are living creatures."
@property
def info(self):
"""@property: 메서드를 속성처럼 사용 가능"""
return f"Name: {self.name}, Age: {self.age}"
dog = Animal("Buddy", 3)
cat = Animal("Kitty", 2)
print(dog.instance_method())
print(Animal.class_method())
print(Animal.static_method())
print(dog.info)
Animal.species = "Mammal"
print(Animal.class_method())
| 메서드 유형 | self 필요 여부 | cls 필요 여부 | 클래스 변수 접근 | 인스턴스 변수 접근 | 주요 용도 |
|---|
| 인스턴스 메서드 | ✅ 필요 | ❌ 불필요 | ✅ 가능 | ✅ 가능 | 인스턴스 속성 조작 |
| 클래스 메서드 | ❌ 불필요 | ✅ 필요 | ✅ 가능 | ❌ 불가능 | 클래스 변수 조작, 새로운 인스턴스 생성 |
| 정적 메서드 | ❌ 불필요 | ❌ 불필요 | ❌ 불가능 | ❌ 불가능 | 독립적인 기능 (유틸리티 함수) |
| 속성 메서드 | ✅ 필요 | ❌ 불필요 | ❌ 불가능 | ✅ 가능 | 메서드를 속성처럼 사용 가능 |
클래스의 특수 메서드
class Example:
"""파이썬의 특수 메서드(Magic Method) 예제"""
def __init__(self, value):
"""객체가 생성될 때 자동 실행되는 생성자"""
self.value = value
def __str__(self):
"""print()로 출력할 때 반환되는 값"""
return f"Example(value={self.value})"
def __repr__(self):
"""개발자가 객체를 확인할 때 반환되는 값"""
return f"Example({self.value})"
def __call__(self, x):
"""객체를 함수처럼 호출할 수 있게 함"""
return self.value * x
def __eq__(self, other):
"""두 객체가 같은지 비교 (== 연산자 오버로딩)"""
return self.value == other.value
def __add__(self, other):
"""+ 연산자 오버로딩"""
return Example(self.value + other.value)
def __len__(self):
"""len() 함수 호출 시 반환되는 값"""
return self.value
e1 = Example(5)
e2 = Example(10)
print(str(e1))
print(repr(e1))
print(e1(3))
print(e1 == e2)
e3 = e1 + e2
print(e3)
print(len(e1))
| 특수 메서드 | 설명 | 사용 예제 |
|---|
__init__() | 객체 생성자 (초기화) | obj = Example(5) |
__str__() | print() 출력 시 반환값 | print(obj) → Example(value=5) |
__repr__() | 개발자용 객체 표현 | repr(obj) → Example(5) |
__call__() | 객체를 함수처럼 호출 가능 | obj(3) → 15 |
__eq__() | == 연산자 오버로딩 | obj1 == obj2 |
__add__() | + 연산자 오버로딩 | obj1 + obj2 |
__len__() | len() 함수 오버로딩 | len(obj) |