728x90
안녕하세요
이번 글에서는 클래스와 객체, 생성자, 캡슐화, 메서드, 속성(Property) 등을
간단한 BankAccount(은행 계좌) 예제로 익혀보겠습니다.
1. 클래스와 객체 기본
- 클래스(class): 설계도
- 객체(object): 설계도로부터 생성된 실제 물건(인스턴스)
class BankAccount:
# 생성자: 객체가 만들어질 때 자동 실행
def __init__(self, owner: str, balance: int = 0):
self.owner = owner
self._balance = balance # 관례상 _로 시작하면 내부용(캡슐화 암시)
# 입금
def deposit(self, amount: int):
if amount <= 0:
raise ValueError("입금액은 0보다 커야 합니다.")
self._balance += amount
# 출금
def withdraw(self, amount: int):
if amount <= 0:
raise ValueError("출금액은 0보다 커야 합니다.")
if amount > self._balance:
raise ValueError("잔액이 부족합니다.")
self._balance -= amount
# 잔액 조회(읽기 전용 속성으로 제공)
@property
def balance(self) -> int:
return self._balance
# 객체를 보기 좋게 표현
def __repr__(self):
return f"BankAccount(owner='{self.owner}', balance={self._balance})"
# 사용 예시
acc = BankAccount("Alice", 1000)
acc.deposit(500)
acc.withdraw(300)
print(acc.balance) # 1200
print(acc) # BankAccount(owner='Alice', balance=1200)
포인트
- __init__ : 생성자
- _balance : 외부 직접 수정 지양(캡슐화 의도)
- @property : 읽기 전용 속성으로 제공 → acc.balance처럼 함수 호출 없이 접근
- __repr__ : 객체 출력 시 가독성 향상
2. 캡슐화와 유효성 검사
직접 속성 수정보다 메서드를 통해서만 변경하도록 설계하면
유효성 검사(음수 금지, 한도 확인 등)를 일관되게 적용할 수 있습니다.
acc = BankAccount("Bob", 0)
try:
acc.deposit(-10) # 예외 발생
except ValueError as e:
print("에러:", e)
try:
acc.withdraw(1) # 예외 발생 (잔액 부족)
except ValueError as e:
print("에러:", e)
3. 클래스 변수 vs 인스턴스 변수
- 인스턴스 변수: 객체마다 다른 값 (self.owner, self._balance)
- 클래스 변수: 모든 객체가 공유하는 값 (예: 계좌 개수 카운트)
class BankAccount:
account_count = 0 # 클래스 변수
def __init__(self, owner: str, balance: int = 0):
self.owner = owner
self._balance = balance
BankAccount.account_count += 1
@classmethod
def created_count(cls) -> int:
return cls.account_count
a1 = BankAccount("A")
a2 = BankAccount("B")
print(BankAccount.created_count()) # 2
- @classmethod : 클래스 자체에 작동(첫 인자 cls)
- 모든 인스턴스가 공유하는 정보(총 생성 수 등)에 적합
4. 정적 메서드와 유틸리티
- 정적 메서드(@staticmethod) : 인스턴스/클래스 상태와 무관한 도우미 함수
class BankAccount:
# ... (생략)
@staticmethod
def is_valid_amount(amount: int) -> bool:
return isinstance(amount, int) and amount > 0
print(BankAccount.is_valid_amount(100)) # True
5. 상속으로 기능 확장
저축예금(SavingAccount) 같은 파생 클래스를 만들어 기능을 확장해 봅니다.
class BankAccount:
def __init__(self, owner: str, balance: int = 0):
self.owner = owner
self._balance = balance
def deposit(self, amount: int):
if amount <= 0:
raise ValueError("입금액은 0보다 커야 합니다.")
self._balance += amount
def withdraw(self, amount: int):
if amount <= 0:
raise ValueError("출금액은 0보다 커야 합니다.")
if amount > self._balance:
raise ValueError("잔액이 부족합니다.")
self._balance -= amount
@property
def balance(self) -> int:
return self._balance
class SavingAccount(BankAccount):
def __init__(self, owner: str, balance: int = 0, rate: float = 0.02):
super().__init__(owner, balance) # 부모 초기화
self.rate = rate
def add_interest(self):
# 단리 이자 적용
interest = int(self.balance * self.rate)
# 부모 메서드 재사용
self.deposit(interest)
acc = SavingAccount("Carol", 10_000, rate=0.05)
acc.add_interest()
print(acc.balance) # 10,500
- SavingAccount는 BankAccount를 상속받아 이자 기능을 추가
- super()로 부모 초기화/메서드 재사용
6. 테스트용 미니 시나리오
실제 동작을 한 번에 확인해봅시다.
def scenario():
a = BankAccount("Alice", 5_000)
b = SavingAccount("Bob", 20_000, rate=0.03)
a.deposit(2_000) # 7,000
try:
a.withdraw(10_000) # 실패
except ValueError as e:
print("[Alice] 출금 실패:", e)
b.add_interest() # 20,000 * 0.03 = 600 → 20,600
b.withdraw(600) # 20,000
print("[Alice] 잔액:", a.balance)
print("[Bob] 잔액:", b.balance)
scenario()
7. 데이터 클래스(dataclass)로 보일러플레이트 줄이기 (선택)
간단한 값 객체는 @dataclass로 초기화/표현을 자동 생성할 수 있습니다.
(주의: 엄격한 캡슐화가 필요한 경우엔 일반 클래스가 더 적합할 수 있습니다.)
from dataclasses import dataclass
@dataclass
class Customer:
name: str
level: int = 1
c = Customer("Alice")
print(c) # Customer(name='Alice', level=1)
▣ 정리
- 클래스/객체로 상태와 행위를 함께 묶는다.
- 캡슐화를 통해 유효성 검사를 일관되게 적용하고, 속성은 @property로 안전하게 노출.
- 클래스 변수/메서드는 공통 메타 정보(생성 수 등)에 적합.
- 상속으로 기능을 확장하고, 필요하면 super()로 부모 로직 재사용.
- 단순 데이터 컨테이너는 @dataclass로 보일러플레이트를 줄일 수 있다.
감사합니다.
728x90
'03_파이썬(Python)' 카테고리의 다른 글
| 파이썬(Python) 기본 문법: 예외 처리 (try-except) (0) | 2025.08.23 |
|---|---|
| 파이썬(Python) 기본 문법: 파일 입출력 (File I/O) (0) | 2025.08.23 |
| 파이썬(Python) 기본 문법: 모듈(Module)과 패키지(Package) (0) | 2025.08.23 |
| 파이썬(Python) 기본 문법: 함수(Function) (0) | 2025.08.23 |
| 파이썬(Python) 기본 문법: 제어문 (if, for, while) (0) | 2025.08.23 |