Python @staticmethod 실습 중심 가이드
이 글은 Python에서 자주 사용되는 @staticmethod를 인스턴스 메서드, 클래스 메서드와 비교하며 실습 중심으로 이해할 수 있도록 정리한 가이드입니다.
1. 메서드 3종류 큰 그림
Python 클래스 안에서 자주 만나는 메서드는 다음 세 가지입니다.
- 인스턴스 메서드 (기본)
@classmethod가 붙은 클래스 메서드@staticmethod가 붙은 정적 메서드
class Demo:
def instance_method(self):
print("인스턴스 메서드, self =", self)
@classmethod
def class_method(cls):
print("클래스 메서드, cls =", cls)
@staticmethod
def static_method():
print("정적 메서드, self/cls 없음")
obj = Demo()
obj.instance_method()
Demo.class_method()
Demo.static_method()
- 인스턴스 메서드 → 개별 객체 상태(
self)와 관련 - 클래스 메서드 → 클래스 자체(
cls)와 관련 - 정적 메서드 → 인스턴스/클래스 상태와 무관한 “독립 함수”지만, 논리적으로 클래스와 묶고 싶을 때 사용
2. @staticmethod의 핵심 개념
@staticmethod는
“클래스 안에 있지만, 인스턴스나 클래스 상태와 전혀 관계 없는 함수”를 정의할 때 사용합니다.
class MathUtil:
@staticmethod
def add(a, b):
return a + b
print(MathUtil.add(3, 5))
이 메서드는 self도, cls도 받지 않으며
MathUtil의 인스턴스를 만들지 않고도 바로 호출할 수 있습니다.
3. @staticmethod가 없을 때와 비교
만약 @staticmethod를 붙이지 않으면 어떻게 될까요?
class MathUtil:
def add(a, b):
return a + b
MathUtil.add(3, 5) # 문제 발생 가능
Python은 클래스 안의 함수를 “메서드”로 취급하고, 첫 번째 인자에 인스턴스나 클래스를 자동으로 바인딩하려 하기 때문에 의도와 다르게 동작하거나 에러를 유발할 수 있습니다.
@staticmethod는 “이 함수는 인스턴스/클래스 바인딩 없이
독립적으로 호출하겠다”라는 것을 Python에게 알려주는 역할을 합니다.
4. 동작 원리 – staticmethod() 함수
@staticmethod는 사실 데코레이터 문법을 쓴 표현입니다.
class MathUtil:
@staticmethod
def add(a, b):
return a + b
위 코드는 아래와 동등합니다.
class MathUtil:
def add(a, b):
return a + b
add = staticmethod(add)
staticmethod() 빌트인 함수가, 해당 함수를
“인스턴스/클래스에 바인딩하지 않는 정적 메서드”로 감싸 주는 역할을 합니다.
5. 실습 1 – 유틸 함수 모으기
문자열 관련 유틸리티를 StringUtil 클래스 안에 모아보겠습니다.
class StringUtil:
@staticmethod
def is_empty(s):
return s is None or s == ""
@staticmethod
def to_upper(s):
if s is None:
return None
return s.upper()
print(StringUtil.is_empty(""))
print(StringUtil.to_upper("hello"))
이 함수들은 인스턴스 상태와 무관하지만, “문자열 처리”라는 공통 주제 아래 클래스에 묶어두면 코드를 읽는 사람이 구조를 이해하기 쉬워집니다.
6. 실습 2 – 클래스와 연결된 계산 로직
원과 관련된 계산 로직을 Circle 클래스 내부에 정리해 봅니다.
import math
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
@staticmethod
def area_from_radius(r):
return math.pi * r ** 2
c = Circle(3)
print(c.area()) # 인스턴스 메서드
print(Circle.area_from_radius(3)) # 정적 메서드
area()는 인스턴스 상태(self.radius)를 사용하지만,
area_from_radius()는 단순히 반지름 값만 있으면 되므로
정적 메서드로 두는 것이 깔끔합니다.
7. 실습 3 – @classmethod와 비교
정적 메서드와 클래스 메서드는 자주 헷갈리므로, 간단한 예제로 비교해 봅니다.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_string(cls, text):
name, age = text.split(",")
return cls(name, int(age))
@staticmethod
def is_adult(age):
return age >= 18
p = Person.from_string("Alice,30")
print(p.name, p.age)
print(Person.is_adult(20))
print(Person.is_adult(15))
from_string→ 새 인스턴스를 만들어 반환하므로cls가 필요 →@classmethodis_adult→ 나이 숫자만 보고 판정, 인스턴스/클래스와 무관 →@staticmethod적합
8. 실습 4 – 인스턴스로도 호출 가능한가?
class Demo:
@staticmethod
def hello():
print("Hello from staticmethod")
d = Demo()
d.hello() # 인스턴스로 호출
Demo.hello() # 클래스로 호출
둘 다 호출이 가능합니다. 다만, 메서드 내부에서는
인스턴스(self)에 접근할 수 없으므로
보통은 Demo.hello()처럼 클래스를 통해 호출하는 스타일이 코드 가독성에 더 좋습니다.
9. 언제 @staticmethod를 쓰면 좋을까?
- 인스턴스의 상태(
self)와 관련이 없을 때 - 클래스 자체(
cls)에도 의존하지 않을 때 - 그럼에도 불구하고 “이 함수는 이 클래스와 개념적으로 연결되어 있다”는 것을 표현하고 싶을 때
예시:
User클래스 안의hash_password(raw_password)Order클래스 안의calculate_tax(price)
“이게 정말 이 클래스에 속하는 개념인가?”를 한 번 생각하고 사용하는 것이 좋습니다.
10. 연습 문제
연습 1 – 온도 변환기
TemperatureConverter 클래스를 만들고, 다음 정적 메서드를 구현해 보세요.
c_to_f(c): 섭씨 → 화씨f_to_c(f): 화씨 → 섭씨
모든 메서드는 @staticmethod를 사용하고, 인스턴스를 만들지 않고 호출하도록 설계해 보세요.
연습 2 – 패스워드 유틸
PasswordUtil 클래스를 만들고:
@staticmethod is_strong(password)- 길이, 특수문자 포함 여부를 기준으로 강도 체크- 나중에
User클래스에서 이 메서드를 활용
“객체 상태와 무관한 로직을 클래스와 어떻게 구조적으로 묶을지”에 대한 감각이 생기게 됩니다.
'프로그래밍 > Python' 카테고리의 다른 글
| [Python] lru_cache는 언제 사용해? (0) | 2025.12.15 |
|---|---|
| [Python] @property는 언제 사용해? (0) | 2025.12.15 |
| [Python] classmethod는 언제 사용해? (0) | 2025.12.15 |
| [Python] decorator에서 wrapper 자세히 보기 (0) | 2025.12.15 |
| [Python] Decorator 입문 훑기 (1) | 2025.12.15 |