파이썬 파일들을 보면 @classmethod, @staticmethod와 같은 데코레이터가 등장하는데 이에 대해 정리하고자 함
일단 클래스에서 사용되는 각 메소드 종류에 대해 알아보기
메소드 종류: 인스턴스 메서드, 정적 메서드, 클래스 메서드
01 instance method 인스턴스 매서드
1. 인스턴스 매서드의 정의
가장 기본이 되는 클래스의 메서드
첫번째 인자로는 항상 self를 적고, 해당 클래스의 인스턴스 값이 넘어옴
# testFile.py 내용
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. 정적 매서드 이해하기
# testFile.py 내용
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
# @staticmethod 주석처리
def my_매서드(): # self 인자 미사용, 인자로 아무것도 받지 않도록 설정
print("my_매서드 호출")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드()
my_매서드()를 인스턴스로 호출한 순간 바로 에러 발생
ERROR 내용: 위에서 생성된 my_매서드()는 인자로 아무것도 받지 않도록 정의되어있으나 1개의 인자가 들어왔다는 내용
즉, 인스턴스로 매서드 호출 시 우리가 인자를 넣지 않아도 자동으로 매서드 인자가 들어간다는 것 확인
그게 바로 self 인자
해결 방법 2가지: 1) my_매서드()에 self 인자를 받을 수 있도록 설정, 또는 2) @staticmethod 사용
1) my_매서드()에 self 인자를 받을 수 있도록 설정
def my_매서드(self): # self 인자 추가
print("my_매서드 호출")
# testFile.py 내용
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
# @staticmethod 주석처리
def my_매서드(self): # self 인자 사용
print("my_매서드 호출 성공")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드()
이럴 경우 my_매서드()는 인스턴스 매서드 (self를 인자로 받는 매서드)가 되는 것
하지만 위와 같이 클래스로 호출 시 에러 발생
ERROR 내용: Blog.my_매서드()에 1개의 인자가 들어와야 하는데 안 들어왔다는 내용
다음과 같이 인자를 넣어주면 해결됨 (맨 마지막 줄)
# testFile.py 내용
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
# @staticmethod 주석처리
def my_매서드(self):
print("my_매서드 호출 성공")
blog = Blog()
print("인스턴스로 호출:")
blog.my_매서드()
print("클래스로 호출:")
Blog.my_매서드("인자") # 인자 추가
2) @staticmethod 사용
@staticmethod # @staticmethod 데코레이터 추가
def my_매서드():
print("my_매서드 호출 성공")
# testFile.py 내용
class Blog:
def __init__(self, name = "Pearl's Blog"):
self.name = name
@staticmethod # @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 인자가 필요 없는 메서드
인스턴스의 속성에 접근 불가
# testFile.py 내용
class Blog:
def __init__(self, name = "Pearl's Blog")
self.name = name
# 정적 매서드
@staticmethod
def to_upper(text: str): # self 인자 미사용
print(text.upper())
blog = Blog()
print(blog.name)
print(Blog.to_upper(blog.name))
2. 정적 매서드의 사용
주로 유틸리티성 함수를 위한 용도로 사용됨
클래스의 어떤 속성에도 변화를 주지 않는 함수이며 입력이 들어오면 항상 같은 출력을 반환하는 순수 함수들이 이에 해당
03 class method 클래스 매서드
1. 클래스 매서드의 정의
클래스의인스턴스 매서드에 @classmethod 데코레이터를 사용하면 클래스 매서드가 됨
첫번째 인자로는 항상 cls를 적고, 해당 클래스 자체가 넘어옴
즉, 클래스를 호출하기 위한 매서드
따라서 인스턴스 매서드와 달리 해당 클래스의 속성에 접근 가능
# testFile.py
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 또한 인스턴스이자 클래스에 포함되기 때문
blog = Blog()
2. 클래스 매서드의 사용
1) 클래스 속성 접근
클래스 속성에 접근하거나 변경하려는 경우 @classmethod 사용 가능
change_platform() 함수의 경우 클래스의 속성인 platform의 값에 접근하고 변경하는 방식으로 사용됨
2) 팩토리 매서드 (factory method)로 사용
특정한 입력 형식으로부터 인스턴스를 생성하려는 경우 @classmethod 사용 가능
from_dict() 함수의 경우 딕셔너리로부터 값을 받아와 인스턴스를 생성하기 위해 생성자를 wrapping하는 용도로 사용됨