실습 과제 1: Fruit 클래스 구현
과일 정보를 관리하는 Fruit 클래스를 구현한다. 이 클래스는 다음 요구사항을 만족해야 한다:
- 클래스 속성 identify: "과일" 값을 가짐
- 객체 속성 name, price: 인스턴스 생성 시 전달
- 클래스 메서드 get_identify(): 클래스 속성 identify 출력
- 객체 메서드 get_total_price(num): 구매 개수와 총 가격 출력
- 정적 메서드 packing(*fruits): 여러 과일 객체를装箱하여 종류별 개수 출력
实现 예시:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Fruit:
"""과일 클래스"""
category = '과일'
def __init__(self, name, price):
self.name = name
self.price = price
@classmethod
def get_identify(cls):
"""클래스 속성 출력"""
print(cls.category)
def get_total_price(self, quantity):
"""총 가격 계산 및 출력"""
total = self.price * quantity
print(f'{quantity}개 {self.name} = {total}원')
@staticmethod
def packing(*items):
"""과일装箱 처리"""
inventory = {}
for item in items:
if '사과' in item.name:
fruit_name = '사과'
elif '바나나' in item.name:
fruit_name = '바나나'
else:
fruit_name = '기타'
inventory[fruit_name] = inventory.get(fruit_name, 0) + 1
print('📦装箱 결과:')
for fruit, count in inventory.items():
print(f' - {fruit}: {count}개')
# 테스트 실행
red_apple = Fruit('빨간사과', 10)
green_apple = Fruit('초록사과', 10)
yellow_banana = Fruit('노란바나나', 8)
thai_banana = Fruit('태국바나나', 88)
Fruit.packing(red_apple, green_apple, yellow_banana, thai_banana)
실습 과제 2: Person 클래스와 property decorator
_person 속성을 캡슐화하고 BMI(체질량지수) 계산기를 구현한다:
- name 속성은 외부에서 접근 및 수정 가능
- bmi 속성은 읽기 전용으로 제공
- BMI 계산식: 男性 (신장cm - 80) × 70% | 女性 (신장cm - 70) × 60%
实现 예시:
class Person:
"""인물 정보 클래스"""
def __init__(self, name, weight, height, gender):
self.name = name
self.weight = weight
self.height = height
self.gender = gender
@property
def bmi(self):
"""BMI 계산 (읽기 전용 속성)"""
if self.gender == '남':
standard_weight = (self.height - 80) * 0.7
else:
standard_weight = (self.height - 70) * 0.6
return round(standard_weight, 2)
# 테스트 실행
student_a = Person('김철수', 75, 180, '남')
print(f'{student_a.name}의 표준 체중: {student_a.bmi}kg')
student_b = Person('이영희', 55, 165, '여')
print(f'{student_b.name}의 표준 체중: {student_b.bmi}kg')
실습 과제 3: 식물 vs 좀비 게임 구현
간단한 게임을 객체지향으로 구현한다:
1) Zombie 클래스
- 기본 HP: 100
- 이름에서 방어구 유형 자동 분석: ['없음', 0], ['로드러운', 5], ['철통', 15]
- @property를 활용한 armor_name (getter/setter/delete), armor_count (getter only)
- armor_name 설정 시 자동으로 이름 변경됨
2) User 클래스
- 이름 속성
- beat(zombie) 메서드: 3초마다 공격,每次 공격 시 25 데미지에서 방어구抵扣
- 좀비死亡 시 게임 종료
3) Game 클래스
- name: "식물_vs_좀비"
- start() 메서드로 게임 시작
- 임의의 좀비 3마리 생성 후 순차적으로 공격
实现 예시:
import time
import random
class Zombie:
"""좀비 클래스"""
ARMOR_INFO = {
'일반 좀비': 0,
'로드러운 좀비': 5,
'철통 좀비': 15
}
def __init__(self, kind):
self.__kind = kind
self.hp = 100
self.armor_value = self.ARMOR_INFO[kind]
@property
def armor_name(self):
"""방어구 이름 조회"""
return self.armor_value, self.__kind
@armor_name.setter
def armor_name(self, new_armor):
"""방어구 이름 설정 (이름 자동 변경)"""
self.__kind = new_armor
self.armor_value = self.ARMOR_INFO[new_armor]
@property
def armor_count(self):
"""방어구 수치 조회 전용"""
return self.armor_value
class Player:
"""플레이어 클래스"""
def __init__(self, username):
self.username = username
def attack(self, zombie):
"""좀비 공격 로직"""
while True:
time.sleep(1)
# 데미지 계산 (방어구 차감)
damage = 25 - zombie.armor_count
damage = max(damage, 1) # 최소 1 데미지
# 좀비死亡 처리
if zombie.hp <= damage:
print(f'⚔️ {self.username}가 {zombie.armor_name[1]}을(를) 처치했습니다!')
break
# 공격 및 남은 체력 출력
zombie.hp -= damage
print(f'{self.username}이(가) {zombie.armor_name[1]}을(를) 공격! '
f'데미지 {damage}, 남은 체력: {zombie.hp}')
class Game:
"""게임 컨트롤러"""
GAME_NAME = "식물_vs_좀비"
@classmethod
def start(cls):
"""게임 시작"""
print(f'🎮 {cls.GAME_NAME} 게임 시작!')
zombie_types = ['일반 좀비', '로드러운 좀비', '철통 좀비']
for turn in range(1, 4):
# 임의의 좀비 생성
kind = random.choice(zombie_types)
zombie = Zombie(kind)
print(f'\n--- {turn}번째 좀비 등장 ---')
print(f'생성된 좀비: {zombie.armor_name[1]}')
# 플레이어 생성 및 공격 시작
player = Player('김 gardener')
player.attack(zombie)
print(f'{turn}번째 좀비 처리 완료!\n')
print('🎉 모든 좀비 처치 완료!')
# 게임 실행
Game.start()
실습 정리
이번 실습을 통해 다음과 같은 Python 객체지향 프로그래밍 개념을 학습했다:
- 클래스 속성: 클래스 전체에서 공유하는 데이터
- 객체 속성: 인스턴스마다 고유한 데이터
- @classmethod: 클래스 자체를 인자로 받는 메서드
- @staticmethod: 인자 없이 정의되는 독립 함수
- @property: 메서드를 속성처럼 접근하는 getter/setter
- 캡슐화: private 속성 (__attr)을 통한 정보 은닉