정적 메서드 와 클래스 메서드 사용하기
지금까지 클래스의 메서드를 사용할 때 인스턴스를 통해서 호출했습니다.
이번에는 인스턴스를 통하지 않고 클래스에서 바로 호출할 수 있는 정적 메서드와 클래스 메서드에 대해 알아보겠습니다.
1. 정적 메서드
class 클래스이름:
@staticmethod
def 메서드(매개변수1, 매개변수2):
코드
class Calc:
@staticmethod
def add(a, b):
print(a + b)
@staticmethod
def mul(a, b):
print(a * b)
Calc.add(10, 20) # 클래스에서 바로 메서드 호출
Calc.mul(10, 20) # 클래스에서 바로 메서드 호출
30
200
정적 메서드는 self를 받지 않으므로 인스턴스 속성에는 접근할 수 없습니다. 그래서 보통 정적 메서드는 인스턴스 속성, 인스턴스 메서드가 필요 없을 때 사용합니다.
여기서 만든 Calc 클래스에 들어있는 add, mul 메서드는 숫자 두개를 받아서 더하거나 곱할 뿐 인스턴스의 속성은 필요하지 않습니다.
그럼 무엇을 정적 메서드로 만들어야 할까요? 정적 메서드는 메서드의 실행이 외부 상태에 영향을 끼치지 않는 순수 함수(pure function)를 만들 때 사용합니다. 순수 함수는 부수 효과(side effect)가 없고 입력 값이 같으면 언제나 같은 출력 값을 반환합니다. 즉, 정적 메서드는 인스턴스의 상태를 변화시키지 않는 메서드를 만들 때 사용합니다.
파이썬의 자료형도 인스턴스 메서드와 정적, 클래스 메서드로 나뉘어져 있습니다. 예를 들어 세트에 요소를 더할 때는 인스턴스 메서드를 사용하고, 합집합을 구할 때는 정적 메서드를 사용하도록 만들어져 있습니다.
>>> a = {1, 2, 3, 4}
>>> a.update({5}) # 인스턴스 메서드
>>> a
{1, 2, 3, 4, 5}
>>> set.union({1, 2, 3, 4}, {5}) # 정적(클래스) 메서드
{1, 2, 3, 4, 5}
이처럼 인스턴스의 내용을 변경해야 할 때는 update와 같이 인스턴스 메서드로 작성하면 되고, 인스턴스 내용과는 상관없이 결과만 구하면 될 때는 set.union과 같이 정적 메서드로 작성하면 됩니다.
2. 클래스 메서드
class 클래스이름:
@classmethod
def 메서드(cls, 매개변수1, 매개변수2):
코드
class Person:
count = 0 # 클래스 속성
def __init__(self):
Person.count += 1 # 인스턴스가 만들어질 때
# 클래스 속성 count에 1을 더함
@classmethod
def print_count(cls):
print('{0}명 생성되었습니다.'.format(cls.count)) # cls로 클래스 속성에 접근
james = Person()
maria = Person()
Person.print_count() # 2명 생성되었습니다.
2명 생성되었습니다.
클래스 메서드는 정적 메서드처럼 인스턴스 없이 호출할 수 있다는 점은 같습니다. 하지만 클래스 메서드는 메서드 안에서 클래스 속성, 클래스 메서드에 접근해야 할 때 사용합니다.
특히 cls를 사용하면 메서드 안에서 현재 클래스의 인스턴스를 만들 수도 있습니다.
즉, cls는 클래스이므로 cls()는 Person()과 같습니다.
@classmethod
def create(cls):
p = cls() # cls()로 인스턴스 생성
return p
[ 연습문제 ]
표준 입력으로 시:분:초 형식의 시간이 입력됩니다. 다음 소스 코드에서 Time 클래스를 완성하여 시, 분, 초가 출력되게 만드세요.
from_string은 문자열로 인스턴스를 만드는 메서드이며 is_time_valid는 문자열이 올바른 시간인지 검사하는 메서드입니다.
시간은 24시까지, 분은 59분까지, 초는 60초까지 있어야 합니다.
정답에 코드를 작성할 때는 class Time:에 맞춰서 들여쓰기를 해주세요.
class Time:
def __init__(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second
@classmethod
def from_string(cls, time_string):
(hour, minute, second) = map(int, time_string.split(":"))
time = cls(hour, minute, second)
return time
@staticmethod
def is_time_valid(time_string):
(hour, minute, second) = map(int, time_string.split(":"))
return hour <= 24 and minute <= 59 and second <= 60
def express(self):
print(f"{self.hour}시 {self.minute}분 {self.second}초")
time_string = input()
if Time.is_time_valid(time_string):
t = Time.from_string(time_string)
t.express()
else:
print("잘못된 시간 형식입니다.")
[ 입력 ]
23:35:59
[ 결과 ]
23 35 59
[ 입력 ]
12:62:43
[ 결과 ]
잘못된 시간 형식입니다.
'BASIC' 카테고리의 다른 글
메서드 오버라이딩 (0) | 2023.11.17 |
---|---|
super() (0) | 2023.11.17 |
특수 메서드 (0) | 2023.11.17 |
비공개 속성, 메서드 사용하기 (0) | 2023.11.17 |
위치 인수, 키워드 인수 (0) | 2023.11.17 |
댓글