Python 객체지향 프로그래밍 실습

실습 과제 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)을 통한 정보 은닉

태그: python OOP class-method staticmethod property-decorator

6월 22일 00:15에 게시됨