[Python] 인스턴스 메소드, 클래스 메소드, 정적(static) 메소드
instance method, class method, static method를 정리해보자.
인스턴스와 클래스는 지난 글에 정리를 했지만 데코레이터와 함께 Market class로 다시 한 번 정리개념이다.
(지난 글 참고(클래스와 인스턴스)) : https://sso-y.tistory.com/13)
(지난 글 참고(데코레이터)) : https://sso-y.tistory.com/15)
인스턴스 메소드
class Market:
# 클래스 변수
stock = 1
location = 'Seoul'
# _ : 인스턴스 변수
def __init__(self, name, office_hours):
self._name = name
self._office_hours = office_hours
# 인스턴스 메소드
def get_time(self):
return '{} Market is open for {} hours'.format(self._name, self._office_hours)
__init__안에 인스턴스 변수를 초기화 해줄 때 변수 선언을 살펴보자.
인스턴스 변수명 앞에 '_(언더바, 언더스코어)' 를 붙이면 클래스 변수와 쉽게 구분할 수 있다.
get_time이라는 Market의 영업시간을 출력하는 인스턴스 메소드를 선언했다.
별도의 데코레이터는 없으며, 첫번째 매개변수로 self가 들어간다.
self는 클래스의 인스턴스를 뜻하고 따라서
- 인스턴스 속성에 접근 가능
클래스 메소드
@classmethod
def stock_info(cls, stock_num):
if stock_num < 1:
return 'out of stock'
cls.stock = stock_num
return 'restocked'
@classmethod를 사용해 클래스 메소드를 선언했다.
클래스 메소드의 첫번째 매개변수는 cls가 들어간다.
cls는 클래스를 뜻한다.
self를 넘겨주지 않으므로
- 인스턴스 속성 접근 불가
- 인스턴스 메소드 접근 불가
stock_info()에서는 넘겨받은 stock_num이 1보다 작으면 품절을 return하고
그렇지 않다면 cls.stock으로 클래스 변수에 접근해 stock_num으로 채운 후 재입고를 return한다.
두 경우 모두 출력해보자.
jmt = Market('JMT', 8)
dalguna = Market('DalGuNa', 4)
print(jmt.stock_info(0), jmt.stock)
print(dalguna.stock)
print(jmt.stock_info(3), jmt.stock)
print(dalguna.stock)

stock_num에 0을 넘겨주자 if문을 통해 return되었다.
초기 stock의 값이 1이었기 때문에 jmt와 dalguna의 stock 또한 변하지 않았다.
stock_num에 3을 넘긴 경우, 클래스 변수 stock의 값을 3으로 변경하여
jmt와 dalguna의 stock이 3으로 출력되었다.
클래스 변수는 공유되는 값이기 때문이다!
정적(static) 메소드
@staticmethod
def location_info(inst):
return '{} is located in {}'.format(inst._name, Market.location)
@staticmethod를 사용해 정적 메소드를 선언했다.
정적 메소드는 첫번째 매개변수로 self나 cls를 요구하지 않는다.
inst는 그냥 내가 넘겨주고 싶은 매개변수이다.
따라서 아래와 같이 설명된다.
- 클래스 속성 접근 불가
- 클래스 메소드 접근 불가
- 인스턴스 속성 접근 불가
- 인스턴스 메소드 접근 불가
정적 메소드를 사용해보자.
print(Market.location_info(dalguna))
print(dalguna.location_info(dalguna))

코드와 같이 정적 메소드는 클래스와 인스턴스에서 접근이 가능하다.
클래스 내부에서는 클래스로 접근해야 하므로 보통 클래스 내/외부에서 클래스로 접근한다.
굳이 static method를 쓰는 이유는 무엇일까?
class method와 비교해보자
static method와 class method 차이
먼저 class method의 예시 코드이다.
class One:
@classmethod
def set_num(cls, num):
cls.num = num
class Two(One):
pass
One.set_num(1)
print(One.num, Two.num)
Two.set_num(2)
print(One.num, Two.num)

@classmethod의 범위는 해당 클래스 내부이다.
따라서 Two은 One을 상속받았기 때문에
class One 내부에도 @classmethod인 set_num이 있고, class Two 내부에도 @classmethod set_num이 있는 것이다.
따라서 Two.set_num()을 호출하면 One.num은 바뀌지 않고 Two.num만 바뀌게 된다.
다음은 static method의 예시 코드이다.
class One:
@staticmethod
def set_num(num):
One.num = num
class Two(One):
pass
One.set_num(1)
print(One.num, Two.num)
Two.set_num(2)
print(One.num, Two.num)

static method는 클래스와 별개의 함수로 생각하는 것이 편하다.
따라서 One.set_num()을 호출하면 클래스와 별개인 set_num(1) 함수를 호출한 것과 같다.
따라서 1 1이 출력되고, 마찬가지로 Two.set_num()을 호출하면 Two클래스와 별개인 set_num(2) 함수를 호출한 결과인 2 2가 되는 것이다.
이런 static method를 왜 사용할까?
위 코드에서 볼 수 있듯이 static method는 class가 객체로 만들어 지기 전에도 사용 가능하다.
하나의 객체에만 종속된 기능이 아니고 특정 클래스에 필요한 기능이기 때문에 객체로 안 만들어도 사용할 수 있도록 하기 위함의 이유가 존재한다.
또한 static method를 클래스.정적메서드명으로 호출을 하기 때문에 해당 함수가 특정 기능(클래스)에 속해 있다는 것을 알기 쉽고, 유사한 기능들을 하나의 클래스 내부에 정의하면 유지 보수가 편리하기 때문에 이러한 경우에 static method를 사용한다.
'Python > 파이썬 중급' 카테고리의 다른 글
| [Python] 네임드 튜플 (namedtuple) (0) | 2022.12.06 |
|---|---|
| [Python] 매직 메소드 (0) | 2022.11.30 |
| [Python] 데코레이터 심화 (0) | 2022.11.29 |
| [Python] __doc__ 메소드 (0) | 2022.11.29 |
| [Python] First-class 함수, Closure 함수, 데코레이터 (Decorator) (0) | 2022.11.22 |