이번 편의 목표: 인스턴스·self·메서드로 같은 규칙을 가진 객체를 만듭니다.
딕셔너리로도 지출 기록기를 만들 수 있습니다. 다만 같은 필드와 같은 규칙을 반복해서 사용하는 경우, 그 자료와 동작을 한곳에 모으고 싶어집니다. 클래스는 이런 묶음의 정의이고, 인스턴스는 그 정의로 만든 개별 객체입니다.
한 지출의 자료와 표시 방법
class Expense:
def __init__(self, item, amount):
if not isinstance(item, str) or not item.strip():
raise ValueError("항목이 필요합니다.")
if type(amount) is not int or amount <= 0:
raise ValueError("금액은 양의 정수여야 합니다.")
self.item = item.strip()
self.amount = amount
def describe(self):
return f"{self.item}: {self.amount:,}원"
coffee = Expense("커피", 4500)
lunch = Expense("점심", 8000)
print(coffee.describe())
print(lunch.describe())
print(coffee.amount + lunch.amount)출력은 `커피: 4,500원`, `점심: 8,000원`, `12500`입니다. `Expense(...)`를 호출하면 개별 인스턴스를 만들고, 초기화 메서드인 `__init__`이 전달받은 값으로 속성을 준비합니다.
`self`는 지금 동작하는 인스턴스를 가리키는 매개변수 이름입니다. `coffee.describe()`를 호출할 때 파이썬이 그 인스턴스를 첫 인수로 전달합니다. 따라서 호출할 때는 `self`를 직접 적지 않습니다. `self.amount`는 각 인스턴스의 금액입니다. 커피와 점심은 서로 다른 값을 가집니다.
검증을 한곳에 모은다
초기화할 때 항목과 금액을 검사하므로 잘못된 자료를 가진 객체가 처음부터 만들어지는 것을 줄일 수 있습니다. `type(amount) is not int`는 여기서 `True` 같은 불리언도 제외하고 정확히 정수만 허용하려는 선택입니다. 파이썬에서 `bool`은 `int`의 하위형이므로 `isinstance(True, int)`는 참이라는 차이가 있습니다.
다만 이 클래스는 생성 후 `coffee.amount = -1` 같은 재대입까지 막지는 않습니다. 객체를 만들 때의 검증과 이후 변경을 통제하는 설계는 다른 문제입니다. 처음부터 속성 접근 제어나 상속을 모두 넣기보다는, 어떤 불변 조건이 필요한지부터 정하는 것이 좋습니다.
언제 클래스로 바꿀까
함수 몇 개와 딕셔너리로 충분한 프로그램이라면 그 상태로 시작해도 됩니다. 객체마다 상태가 있고 같은 동작을 반복한다면 클래스를 고려합니다. 자료를 담는 역할이 중심이면 표준 라이브러리의 `dataclasses`도 선택지가 됩니다.
이 연재의 마지막 프로젝트는 CSV와 연결하기 쉬운 딕셔너리 구조를 유지합니다. 클래스 편을 넣었다고 마지막 코드까지 무조건 클래스로 바꿀 필요는 없습니다. 문법을 배운 뒤 목적에 맞게 선택하는 것이 중요합니다.
직접 해 보기
현재 잔액을 가진 `Wallet` 클래스를 만들고, 양의 정수만 입금하는 메서드를 추가하세요. 인스턴스마다 잔액이 따로 유지되도록 만드세요.
해설
class Wallet:
def __init__(self):
self.balance = 0
def deposit(self, amount):
if type(amount) is not int or amount <= 0:
raise ValueError("양의 정수만 입금할 수 있습니다.")
self.balance += amount
first = Wallet()
second = Wallet()
first.deposit(10000)
print(first.balance)
print(second.balance)결과는 `10000`, `0`입니다. `balance`를 `self`에 연결했으므로 두 인스턴스의 잔액이 분리됩니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
등록된 댓글이 없습니다.