Python
@classmethod, @staticmethod (파이썬 매서드 데코레이터)
by yororing
2024. 7. 1.
00 개요
- 파이썬 파일들을 보면 @classmethod, @staticmethod와 같은 데코레이터가 등장하는데 이에 대해 정리하고자 함
- 일단 클래스에서 사용되는 각 메소드 종류에 대해 알아보기
- 메소드 종류: 인스턴스 메서드, 정적 메서드, 클래스 메서드
01 instance method 인스턴스 매서드
1. 인스턴스 매서드의 정의
- 가장 기본이 되는 클래스의 메서드
- 첫번째 인자로는 항상 self를 적고, 해당 클래스의 인스턴스 값이 넘어옴
class Blog:
def __init__(self, name="Pearl's blog"):
self.name = name
def print_name(self):
print(self.name)
blog = Blog()
print(blog.print_name())
02 static method 정적 매서드
0. 정적 매서드 이해하기
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
def my_매서드():
print("my_매서드 호출")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드()
- my_매서드()를 인스턴스로 호출한 순간 바로 에러 발생
- ERROR 내용: 위에서 생성된 my_매서드()는 인자로 아무것도 받지 않도록 정의되어있으나 1개의 인자가 들어왔다는 내용
- 즉, 인스턴스로 매서드 호출 시 우리가 인자를 넣지 않아도 자동으로 매서드 인자가 들어간다는 것 확인
- 해결 방법 2가지: 1) my_매서드()에 self 인자를 받을 수 있도록 설정, 또는 2) @staticmethod 사용
- 1) my_매서드()에 self 인자를 받을 수 있도록 설정
def my_매서드(self):
print("my_매서드 호출")
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
def my_매서드(self):
print("my_매서드 호출 성공")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드()
- 이럴 경우 my_매서드()는 인스턴스 매서드 (self를 인자로 받는 매서드)가 되는 것
- 하지만 위와 같이 클래스로 호출 시 에러 발생
- ERROR 내용: Blog.my_매서드()에 1개의 인자가 들어와야 하는데 안 들어왔다는 내용
- 다음과 같이 인자를 넣어주면 해결됨 (맨 마지막 줄)
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
def my_매서드(self):
print("my_매서드 호출 성공")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드("인자")
@staticmethod
def my_매서드():
print("my_매서드 호출 성공")
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
@staticmethod
def my_매서드():
print("my_매서드 호출 성공")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드()
- @staticmethod를 사용하니 인스턴스로서의 호출(i.e., 인스턴스.매서드() )도, 클래스로서의 호출(i.e., 클래스.매서드() )도 모두 정상적으로 작동하는 것 확인
- 즉, @staticmethod는 인자가 필요 없는 클래스 내 정적 매서드를 실행할 수 있도록 도와주는 데코레이터 (인스턴스/클래스 상관 없이!)
1. 정적 매서드의 정의
- 클래스의 인스턴스 매서드에 @staticmethod 데코레이터를 사용하면 정적 매서드가 됨
- 인스턴스 매서드에서 사용되는 self 인자 또는 클래스 매서드에서 사용되는 cls 인자 불필요
- 즉, self, cls 인자가 필요 없는 메서드
- 인스턴스의 속성에 접근 불가
class Blog:
def __init__(self, name = "Pearl's Blog")
self.name = name
# 정적 매서드
@staticmethod
def to_upper(text: str):
print(text.upper())
blog = Blog()
print(blog.name)
print(Blog.to_upper(blog.name))
2. 정적 매서드의 사용
- 주로 유틸리티성 함수를 위한 용도로 사용됨
- 클래스의 어떤 속성에도 변화를 주지 않는 함수이며 입력이 들어오면 항상 같은 출력을 반환하는 순수 함수들이 이에 해당
03 class method 클래스 매서드
1. 클래스 매서드의 정의
- 클래스의 인스턴스 매서드에 @classmethod 데코레이터를 사용하면 클래스 매서드가 됨
- 첫번째 인자로는 항상 cls를 적고, 해당 클래스 자체가 넘어옴
- 즉, 클래스를 호출하기 위한 매서드
- 따라서 인스턴스 매서드와 달리 해당 클래스의 속성에 접근 가능
class Blog:
platform: str = "tistory"
def __init__(self, name = "Pearl's Blog"):
self.name = name
@classmethod
def change_platform(cls, platform: str):
cls.platform = platform
@classmethod
def from_dict(cls, dic: dict):
return cls(dic["name"])
blog = Blog()
print("class' platform: %s" % blog.platform)
Blog.change_platform("naver")
print("change_platform (instance): %s" % blog.platform)
print("change_platform (class): %s" % Blog.platform)
blog2 = Blog.from_dict({"name": "Dayoon's Blog"})
print("from_dict: %s" % blog2.name)
- blog는 인스턴스인데 호출되는 이유: blog 또한 인스턴스이자 클래스에 포함되기 때문
2. 클래스 매서드의 사용
1) 클래스 속성 접근
- 클래스 속성에 접근하거나 변경하려는 경우 @classmethod 사용 가능
- change_platform() 함수의 경우 클래스의 속성인 platform의 값에 접근하고 변경하는 방식으로 사용됨
2) 팩토리 매서드 (factory method)로 사용
- 특정한 입력 형식으로부터 인스턴스를 생성하려는 경우 @classmethod 사용 가능
- from_dict() 함수의 경우 딕셔너리로부터 값을 받아와 인스턴스를 생성하기 위해 생성자를 wrapping하는 용도로 사용됨
참조
- https://leffept.tistory.com/441#classmethod%--%EB%-E%--%-F
- https://daco2020.tistory.com/281
-
-