Topic 3: 생성자와 초기화 - 객체의 첫 설정 ⚙️
🎯 학습 목표
init 메서드에 매개변수를 추가하여 객체 생성 시 원하는 정보로 초기화할 수 있고, 같은 클래스로 서로 다른 특성을 가진 객체들을 만들 수 있습니다.
🏭 생성자(Constructor)란?
객체의 첫 번째 설정
생성자는 객체가 만들어질 때 가장 먼저 실행되는 특별한 메서드입니다.
실생활 비유:
- 자동차 공장에서 차를 만들 때: 색깔, 모델, 옵션을 먼저 정함
- 신분증을 만들 때: 이름, 주민번호, 주소를 먼저 기입
- 휴대폰을 설정할 때: 사용자 이름, 언어, 배경화면을 먼저 설정
init 메서드
파이썬에서 생성자는 __init__
이라는 특별한 이름을 가집니다.
class Student:
def __init__(self): # 생성자 메서드
print("새로운 학생 객체가 만들어졌습니다!")
self.name = "이름 없음"
self.age = 0
# 객체 생성하면 자동으로 __init__ 실행
student = Student() # "새로운 학생 객체가 만들어졌습니다!" 출력
📝 매개변수가 있는 생성자
정보를 받아서 초기화하기
class Student:
def __init__(self, name, age, grade):
# 매개변수로 받은 값들을 속성에 저장
self.name = name
self.age = age
self.grade = grade
print(f"{name} 학생이 생성되었습니다!")
def introduce(self):
print(f"안녕하세요! {self.name}입니다.")
print(f"나이는 {self.age}세, {self.grade}학년입니다.")
# 서로 다른 정보로 학생들 생성
kim_cheolsu = Student("김철수", 16, 2)
lee_younghee = Student("이영희", 15, 1)
park_minsu = Student("박민수", 17, 3)
# 각자 다른 정보를 가짐
kim_cheolsu.introduce()
lee_younghee.introduce()
park_minsu.introduce()
자동차 공장 예시
class Car:
def __init__(self, brand, model, color, year):
self.brand = brand # 브랜드
self.model = model # 모델
self.color = color # 색깔
self.year = year # 연식
self.speed = 0 # 초기 속도
self.mileage = 0 # 초기 주행거리
print(f"{year}년형 {brand} {model}({color}) 생산 완료! 🚗")
def show_info(self):
print(f"=== 차량 정보 ===")
print(f"브랜드: {self.brand}")
print(f"모델: {self.model}")
print(f"색깔: {self.color}")
print(f"연식: {self.year}년")
print(f"주행거리: {self.mileage:,}km")
# 다양한 자동차들 생산
my_car = Car("현대", "소나타", "흰색", 2023)
friend_car = Car("기아", "K5", "검정", 2022)
family_car = Car("BMW", "320i", "파랑", 2024)
print("\n=== 차량 정보 확인 ===")
my_car.show_info()
print()
friend_car.show_info()
🎛️ 기본값 매개변수
선택적 정보 설정
class BankAccount:
def __init__(self, owner, account_number, initial_balance=0):
self.owner = owner # 필수 정보
self.account_number = account_number # 필수 정보
self.balance = initial_balance # 선택적 정보 (기본값 0)
print(f"💳 {owner}님의 계좌가 개설되었습니다!")
print(f"계좌번호: {account_number}")
print(f"초기 잔액: {initial_balance:,}원")
def show_account_info(self):
print(f"=== 계좌 정보 ===")
print(f"예금주: {self.owner}")
print(f"계좌번호: {self.account_number}")
print(f"잔액: {self.balance:,}원")
# 다양한 방법으로 계좌 개설
account1 = BankAccount("김철수", "123-456-789") # 잔액 0원으로 시작
account2 = BankAccount("이영희", "987-654-321", 100000) # 잔액 10만원으로 시작
account3 = BankAccount("박민수", "555-777-999", 50000) # 잔액 5만원으로 시작
print("\n=== 계좌 정보 확인 ===")
account1.show_account_info()
print()
account2.show_account_info()
게임 캐릭터 생성
class GameCharacter:
def __init__(self, name, character_class="전사", level=1):
self.name = name
self.character_class = character_class
self.level = level
# 직업별 초기 능력치 설정
if character_class == "전사":
self.hp = 120
self.attack = 20
self.defense = 15
elif character_class == "마법사":
self.hp = 80
self.attack = 25
self.defense = 8
elif character_class == "궁수":
self.hp = 100
self.attack = 22
self.defense = 12
else:
self.hp = 100
self.attack = 15
self.defense = 10
print(f"🎮 {character_class} {name}가 생성되었습니다! (Lv.{level})")
def show_status(self):
print(f"=== {self.name}의 상태 ===")
print(f"직업: {self.character_class}")
print(f"레벨: {self.level}")
print(f"HP: {self.hp}")
print(f"공격력: {self.attack}")
print(f"방어력: {self.defense}")
# 다양한 캐릭터 생성
character1 = GameCharacter("드래곤슬레이어") # 기본 전사
character2 = GameCharacter("아이스퀸", "마법사") # 마법사
character3 = GameCharacter("로빈후드", "궁수", 5) # 5레벨 궁수
print("\n=== 캐릭터 정보 ===")
character1.show_status()
print()
character2.show_status()
print()
character3.show_status()
📚 실용적인 클래스 예시들
예시 1: 도서관 책 관리
class Book:
def __init__(self, title, author, isbn, genre="일반"):
self.title = title # 제목
self.author = author # 저자
self.isbn = isbn # ISBN
self.genre = genre # 장르
self.is_borrowed = False # 대출 상태
self.borrower = None # 대출자
print(f"📚 『{title}』이 도서관에 등록되었습니다!")
def borrow(self, borrower_name):
if not self.is_borrowed:
self.is_borrowed = True
self.borrower = borrower_name
print(f"📖 {borrower_name}님이 『{self.title}』을 대출했습니다.")
else:
print(f"이미 {self.borrower}님이 대출 중입니다.")
def return_book(self):
if self.is_borrowed:
print(f"📚 {self.borrower}님이 『{self.title}』을 반납했습니다.")
self.is_borrowed = False
self.borrower = None
else:
print("이미 반납된 책입니다.")
def show_info(self):
print(f"=== 도서 정보 ===")
print(f"제목: {self.title}")
print(f"저자: {self.author}")
print(f"장르: {self.genre}")
print(f"상태: {'대출중' if self.is_borrowed else '대출가능'}")
if self.is_borrowed:
print(f"대출자: {self.borrower}")
# 도서관 책들 등록
book1 = Book("해리포터", "J.K. 롤링", "978-123456", "판타지")
book2 = Book("이것이 파이썬이다", "박응용", "978-789012", "컴퓨터")
book3 = Book("데미안", "헤르만 헤세", "978-345678")
# 도서 대출/반납
book1.borrow("김철수")
book2.borrow("이영희")
book1.return_book()
print("\n=== 도서 현황 ===")
book1.show_info()
print()
book2.show_info()
예시 2: 온라인 쇼핑몰 상품
class Product:
def __init__(self, name, price, category, stock=0, discount=0):
self.name = name # 상품명
self.price = price # 가격
self.category = category # 카테고리
self.stock = stock # 재고
self.discount = discount # 할인율 (0~1)
self.sales_count = 0 # 판매 수량
print(f"🛍️ {name} 상품이 등록되었습니다!")
def get_discounted_price(self):
"""할인된 가격 계산"""
return int(self.price * (1 - self.discount))
def sell(self, quantity=1):
"""상품 판매"""
if self.stock >= quantity:
self.stock -= quantity
self.sales_count += quantity
total_price = self.get_discounted_price() * quantity
print(f"💰 {self.name} {quantity}개 판매완료!")
print(f"결제금액: {total_price:,}원")
print(f"남은 재고: {self.stock}개")
else:
print(f"❌ 재고가 부족합니다! (현재 재고: {self.stock}개)")
def restock(self, quantity):
"""재고 추가"""
self.stock += quantity
print(f"📦 {self.name} {quantity}개 입고완료! (총 재고: {self.stock}개)")
def show_product_info(self):
original_price = self.price
discounted_price = self.get_discounted_price()
print(f"=== {self.name} 상품정보 ===")
print(f"카테고리: {self.category}")
print(f"정가: {original_price:,}원")
if self.discount > 0:
print(f"할인가: {discounted_price:,}원 ({self.discount*100:.0f}% 할인)")
print(f"재고: {self.stock}개")
print(f"판매량: {self.sales_count}개")
# 온라인 쇼핑몰 상품들
laptop = Product("게이밍 노트북", 1200000, "전자제품", 10, 0.1)
mouse = Product("무선 마우스", 45000, "컴퓨터 액세서리", 50)
keyboard = Product("기계식 키보드", 120000, "컴퓨터 액세서리", 20, 0.15)
# 상품 판매
laptop.sell(1)
mouse.sell(3)
keyboard.sell(2)
# 재고 추가
mouse.restock(30)
print("\n=== 상품 현황 ===")
laptop.show_product_info()
print()
mouse.show_product_info()
예시 3: 학급 성적 관리
class StudentRecord:
def __init__(self, name, student_id, grade, class_num):
self.name = name
self.student_id = student_id
self.grade = grade
self.class_num = class_num
self.subjects = {} # 과목별 점수 저장
self.attendance = 100 # 출석률
print(f"📝 {grade}학년 {class_num}반 {name} 학생 등록완료!")
def add_score(self, subject, score):
"""과목 점수 추가"""
if 0 <= score <= 100:
self.subjects[subject] = score
print(f"📊 {self.name} - {subject}: {score}점 기록")
else:
print("점수는 0~100 사이여야 합니다!")
def calculate_average(self):
"""평균 점수 계산"""
if self.subjects:
return sum(self.subjects.values()) / len(self.subjects)
return 0
def get_grade(self):
"""등급 계산"""
avg = self.calculate_average()
if avg >= 90:
return "A"
elif avg >= 80:
return "B"
elif avg >= 70:
return "C"
elif avg >= 60:
return "D"
else:
return "F"
def show_report_card(self):
"""성적표 출력"""
print(f"=== {self.name} 성적표 ===")
print(f"학번: {self.student_id}")
print(f"학급: {self.grade}학년 {self.class_num}반")
print(f"출석률: {self.attendance}%")
print("\n📚 과목별 성적:")
for subject, score in self.subjects.items():
print(f" {subject}: {score}점")
avg = self.calculate_average()
grade = self.get_grade()
print(f"\n📈 평균: {avg:.1f}점 (등급: {grade})")
# 학생들 등록
kim_cheolsu = StudentRecord("김철수", "20240101", 2, 3)
lee_younghee = StudentRecord("이영희", "20240102", 2, 3)
# 성적 입력
kim_cheolsu.add_score("국어", 85)
kim_cheolsu.add_score("영어", 92)
kim_cheolsu.add_score("수학", 78)
lee_younghee.add_score("국어", 88)
lee_younghee.add_score("영어", 85)
lee_younghee.add_score("수학", 95)
# 성적표 출력
print("\n=== 성적표 출력 ===")
kim_cheolsu.show_report_card()
print()
lee_younghee.show_report_card()
🔄 초기화 패턴들
패턴 1: 계산된 속성
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
self.area = width * height # 계산된 속성
self.perimeter = 2 * (width + height) # 계산된 속성
print(f"📐 {width}×{height} 직사각형 생성")
print(f"넓이: {self.area}, 둘레: {self.perimeter}")
# 직사각형들 생성
rectangle1 = Rectangle(10, 5)
rectangle2 = Rectangle(8, 8)
패턴 2: 조건부 초기화
class Employee:
def __init__(self, name, position, salary):
self.name = name
self.position = position
self.salary = salary
# 직급에 따른 혜택 자동 설정
if position == "사장":
self.vacation_days = 30
self.parking_spot = True
self.office_type = "개인사무실"
elif position == "부장":
self.vacation_days = 25
self.parking_spot = True
self.office_type = "팀사무실"
elif position == "과장":
self.vacation_days = 20
self.parking_spot = True
self.office_type = "팀사무실"
else:
self.vacation_days = 15
self.parking_spot = False
self.office_type = "오픈오피스"
print(f"👔 {position} {name}님이 입사했습니다!")
def show_benefits(self):
print(f"=== {self.name}님의 혜택 ===")
print(f"연차: {self.vacation_days}일")
print(f"주차공간: {'있음' if self.parking_spot else '없음'}")
print(f"사무실: {self.office_type}")
# 다양한 직급의 직원들
boss = Employee("김사장", "사장", 8000)
manager = Employee("이부장", "부장", 6000)
new_employee = Employee("박신입", "사원", 3000)
print("\n=== 혜택 정보 ===")
boss.show_benefits()
print()
new_employee.show_benefits()
🚨 자주 발생하는 오류
오류 1: 필수 매개변수 누락
class Student:
def __init__(self, name, age, grade): # 3개 모두 필수
self.name = name
self.age = age
self.grade = grade
# ❌ 매개변수 부족
# student = Student("김철수") # TypeError: 나이와 학년이 없음
# ✅ 모든 매개변수 제공
student = Student("김철수", 16, 2)
오류 2: 매개변수 순서 혼동
class Car:
def __init__(self, brand, model, year, color):
self.brand = brand
self.model = model
self.year = year
self.color = color
# ❌ 순서 틀림
# wrong_car = Car("빨강", "소나타", 2023, "현대") # 잘못된 순서
# ✅ 올바른 순서
correct_car = Car("현대", "소나타", 2023, "빨강")
# ✅ 키워드 인수로 명확하게
keyword_car = Car(brand="현대", model="소나타", year=2023, color="빨강")
오류 3: self 속성 설정 누락
class Book:
def __init__(self, title, author):
# ❌ self 없이 지역 변수로만 저장
# title = title # 객체 속성이 되지 않음
# author = author # 객체 속성이 되지 않음
# ✅ self로 객체 속성 설정
self.title = title
self.author = author
book = Book("파이썬 입문", "김개발")
print(book.title) # 정상 출력
print(book.author) # 정상 출력
💡 퀴즈: 생성자와 초기화 이해도 체크
Q1. 다음 코드에서 생성자는?
class Car:
def __init__(self, brand): # A
self.brand = brand
def start(self): # B
print("시동!")
def drive(self): # C
print("운전!")
- A만
- B만
- C만
- A, B, C 모두
💡 정답 확인
정답: 1번 (A만)
__init__
메서드가 생성자입니다. 객체가 생성될 때 자동으로 호출되어 초기화를 담당합니다.
Q2. 다음 코드의 실행 결과는?
class Student:
def __init__(self, name, grade=1):
self.name = name
self.grade = grade
student1 = Student("김철수")
student2 = Student("이영희", 3)
print(f"{student1.name}: {student1.grade}학년")
print(f"{student2.name}: {student2.grade}학년")
- 김철수: 1학년, 이영희: 3학년
- 김철수: 0학년, 이영희: 3학년
- 오류 발생
- 김철수: None학년, 이영희: 3학년
💡 정답 확인
정답: 1번 (김철수: 1학년, 이영희: 3학년)
grade=1
은 기본값 매개변수이므로, student1
은 기본값 1을 사용하고 student2
는 명시적으로 3을 받습니다.
Q3. 매개변수가 있는 생성자의 장점은?
- 코드가 짧아진다
- 객체마다 다른 초기값을 설정할 수 있다
- 실행 속도가 빨라진다
- 메모리 사용량이 줄어든다
💡 정답 확인
정답: 2번 (객체마다 다른 초기값을 설정할 수 있다)
매개변수가 있는 생성자를 사용하면 같은 클래스로 만든 객체들이 각각 다른 초기값을 가질 수 있어 유연성이 크게 향상됩니다.
✅ 생성자와 초기화 마스터 체크리스트
✅ 생성자와 초기화 마스터 체크리스트
🌟 다음 단계 미리보기
생성자와 초기화를 익혔으니, 이제 실전에서 활용할 수 있는 완전한 클래스를 만들어보겠습니다!
다음 토픽에서는:
- 복잡한 기능 구현: 여러 메서드가 협력하는 클래스
- 상태 관리: 객체의 상태 변화 추적
- 실전 프로젝트: 은행 시스템, 게임 캐릭터, 쇼핑몰 등
예를 들어:
class BankAccount:
def __init__(self, owner, initial_balance=0):
self.owner = owner
self.balance = initial_balance
self.transaction_history = []
def deposit(self, amount):
self.balance += amount
self.transaction_history.append(f"입금: +{amount:,}원")
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
self.transaction_history.append(f"출금: -{amount:,}원")
return True
return False
def get_statement(self):
for transaction in self.transaction_history:
print(transaction)
실제 프로그램에서 사용할 수 있는 클래스가 됩니다! 🚀
Last updated on