class Example:
@staticmethod
def add(a, b):
return a + b
res_1 = Example.add(3, 5) # OK
res_2 = Example().add(3, 5) # OK (인스턴스로도 가능하지만 self를 안 씀)
print(res_1, res_2)8 8
October 23, 2025
@staticmethod는 클래스 내부에 있지만, 인스턴스(self)나 클래스(cls)에 의존하지 않는 함수를 정의할 때 사용합니다.
class Example:
@staticmethod
def add(a, b):
return a + b
res_1 = Example.add(3, 5) # OK
res_2 = Example().add(3, 5) # OK (인스턴스로도 가능하지만 self를 안 씀)
print(res_1, res_2)8 8
@staticmethod를 쓰는 이유self 인자를 받아 인스턴스의 상태(속성)에 접근합니다.@staticmethod는 그런 게 필요 없을 때 사용합니다.→ square()는 어떤 객체의 상태와도 관계없으므로 정적 메서드로 분리하는 게 논리적으로 깔끔합니다.
이렇게 하면 코드 구조가 더 명확해집니다:
@classmethod)와의 차이| 구분 | 일반 메서드 | @classmethod |
@staticmethod |
|---|---|---|---|
| 첫 번째 인자 | self |
cls |
없음 |
| 인스턴스 접근 | 가능 | 불가능 | 불가능 |
| 클래스 접근 | 가능 (self.class) | 가능 | 불가능 |
| 주 용도 | 인스턴스 동작 정의 | 클래스 전체 관련 동작 정의 | 독립적 유틸 함수 정의 |
class Person:
species = "Human"
def __init__(self, name):
self.name = name
def introduce(self):
return f"I’m {self.name}"
@classmethod
def describe_species(cls):
return f"All persons are {cls.species}"
@staticmethod
def is_adult(age):
return age >= 18| 호출 예시 | 결과 |
|---|---|
Person("Avery").introduce() |
“I’m Avery” |
Person.describe_species() |
“All persons are Human” |
Person.is_adult(20) |
True |
| 상황 | 사용 |
|---|---|
인스턴스 상태(self)를 써야 함 |
일반 메서드 |
클래스 속성(cls)을 써야 함 |
@classmethod |
| 둘 다 필요 없음 | @staticmethod |
그럼 아래에 3가지 메서드(일반, @classmethod, @staticmethod) 를 한 클래스 안에서 비교해볼게요.
class Example:
# 클래스 변수 (모든 인스턴스가 공유)
species = "Human"
def __init__(self, name):
self.name = name # 인스턴스 변수 (각자 다름)
# ① 일반 메서드 (인스턴스에 종속)
def introduce(self):
print(f"안녕, 나는 {self.name}야!") # self 사용
# ② 클래스 메서드 (클래스 자체에 종속)
@classmethod
def change_species(cls, new_species):
cls.species = new_species # cls 사용
print(f"이제 모든 인스턴스의 species가 '{cls.species}'로 변경됨!")
# ③ 정적 메서드 (독립적 유틸 함수)
@staticmethod
def is_adult(age):
return age >= 18# 인스턴스 생성
a = Example("Avery")
b = Example("Yeon")
# ① 일반 메서드
a.introduce() # "안녕, 나는 Avery야!"
b.introduce() # "안녕, 나는 Yeon야!"
# ② 클래스 메서드
Example.change_species("Robot") # 클래스 전체에 적용
print(a.species) # 👉 "Robot"
print(b.species) # 👉 "Robot"
# ③ 정적 메서드
print(Example.is_adult(20)) # True
print(Example.is_adult(15)) # False안녕, 나는 Avery야!
안녕, 나는 Yeon야!
이제 모든 인스턴스의 species가 'Robot'로 변경됨!
Robot
Robot
True
False
| 구분 | 일반 메서드 (def) |
클래스 메서드 (@classmethod) |
정적 메서드 (@staticmethod) |
|---|---|---|---|
| 첫 번째 인자 | self |
cls |
없음 |
| 접근 대상 | 인스턴스 속성 | 클래스 속성 | 없음 |
| 호출 방식 | obj.method() |
Class.method() 또는 obj.method() |
Class.method() 또는 obj.method() |
| 인스턴스 필요 | 필요 | ❌ 불필요 | ❌ 불필요 |
| 대표 용도 | 객체의 동작 정의 | 클래스 전체 설정 변경 | 독립적인 유틸리티 함수 |
| 예시 | self.name 접근 |
cls.species 변경 |
나이 ≥ 18 판단 등 계산용 |
| 상황 | 적절한 선택 |
|---|---|
| 인스턴스의 상태(속성)를 다뤄야 함 | → 일반 메서드 |
| 클래스 전체의 상태나 설정을 다뤄야 함 | → @classmethod |
| 독립적인 계산/검증 기능 (상태 무관) | → @staticmethod |
flowchart TD
%% =========================================
%% 1️⃣ 일반 메서드 (Instance Method)
%% =========================================
subgraph A["① 일반 메서드 (instance method)"]
direction LR
A1["Class Example"]
A2["Instance a = Example('Avery')"]
A3["a.introduce() 호출"]
A4["→ self = a (인스턴스 자신)"]
A5["→ 인스턴스 속성 접근 가능 (self.name 등)"]
A1 --> A2
A2 --> A3
A3 --> A4 --> A5
end
%% =========================================
%% 2️⃣ 클래스 메서드 (Class Method)
%% =========================================
subgraph B["② 클래스 메서드 (classmethod)"]
direction LR
B1["Class Example"]
B2["Example.change_species('Robot') 호출"]
B3["→ cls = Example (클래스 자신)"]
B4["→ 클래스 속성 접근/변경 (cls.species 등)"]
B1 --> B2
B2 --> B3 --> B4
end
%% =========================================
%% 3️⃣ 정적 메서드 (Static Method)
%% =========================================
subgraph C["③ 정적 메서드 (staticmethod)"]
direction LR
C1["Class Example"]
C2["Example.is_adult(20) 호출"]
C3["→ self/cls 없음"]
C4["→ 외부 입력만 처리 (age >= 18 등)"]
C1 --> C2
C2 --> C3 --> C4
end
%% =========================================
%% 연결선
A5 -.-> B1
B4 -.-> C1