안녕하세요~~~!!
27년차 진로탐색꾼 조녁입니다!!
이번엔 class에 대해서 정리해볼까합니다! 강의를 들은 지 시간이 꽤 흘렀는데 정리는 항상 늦어지네요 ㅠㅠ
클래스는 재밌는 내용도 많고 유용하게 쓰이는 부분들이라 2개로 나눠서 상세하게 정리해두려고 합니다!! (그냥 길어요 ..)
강의에선 클래스 설명을 스타크래프트 게임에 빗대어서 설명해주고 계십니다. 상상력을 더하시면 더 잘 이해되실 거라고 생각합니다!!
모든 코드는 아래 git_hub 에 올려둔 Colab 노트북 참고 부탁드려요.
github.com/jonhyuk0922/Python-basic
파이썬 설치 방법은 아래 글 참고해주세요! (주피터 노트북 환경 + 구글 클라우드 사용이 가능한 Colab 환경 추천드립니다.)
파이썬 기초 6-1 강 내용
1. 클래스
2. init
3. 멤버변수
4. 메소드
5. 상속
6.다중 상속
1. 클래스
: 우리가 만들 스타크래프트 유닛(마린, 탱크)이 붕어빵이라면, 클래스는 붕어빵틀을 의미합니다.
#마린 : 공격유닛, 군인. 총을 쏠 수 있음
name = "마린" #유닛의 이름
hp = 40 #유닛의 체력
damage = 5 #유닛의 공격력
print(f"{name}유닛이 생성되었습니다.")
print(f"체력 {hp}, 공격력 {damage}\n")
우선 마린을 만들어봤습니다. 유닛의 특징(체력 , 공격력)을 정의하고 print 해봅니다. 다음으론 탱크를 만들 겁니다.
#탱크 : 공격 유닛, 탱크. 포를 쏠 수 있는데, 일반 모드 / 시즈 모드.
tank_name = "탱크"
tank_hp = 150
tank_damage = 35
print(f"{tank_name}유닛이 생성되었습니다.")
print(f"체력 {tank_hp}, 공격력 {tank_damage}\n")
그런데 매번 이렇게 유닛을 정의하는 게 너무 번거롭지 않을까요? 그런 생각을 했다고 칩시다. 이 때 등장하는 것이 클래스입니다.
class Unit:
def __init__(self,name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
print(f"{self.name} 유닛이 생성 되었습니다.")
print(f"체력 : {self.hp}, 공격력 : {self.damage}")
marine1 = Unit("마린",40,5)
marine2 = Unit("마린",40,5)
tank = Unit("탱크",150,35)
위와 같이 클래스(틀)을 만들고 유닛을 찍어낼 수 있습니다.
이제 유닛들을 만들어봤으니 취할 수 있는 액션을 정의해볼 건데, 많이 쓰이는 공격을 정의해 보겠습니다. (스타크래프트는 어택땅이죠.)
def attack(name, location, damage):
print(f"{name} : {location} 방향으로 적군을 공격 합니다. [공격력 {damage}]")
attack(name, "1시", damage)
attack(tank_name, "1시", tank_damage)
attack(tank2_name, "1시", tank2_damage)
2. init
: 파이썬에서 쓰이는 생성자입니다. 객체를 생성할 때는 이 생성자의 전달값에 해당하는 갯수만큼 값을 입력해줘야 합니다. (단, self 제외)
class Unit:
def __init__(self,name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
print(f"{self.name} 유닛이 생성 되었습니다.")
print(f"체력 : {self.hp}, 공격력 : {self.damage}")
marine1 = Unit("마린",40,5)
marine2 = Unit("마린",40,5)
tank = Unit("탱크",150,35)
3. 멤버변수
: 클래스 내에서 정의된 변수로, self와 함께 사용될 수 있습니다.
eg) name , hp , damage ...
# 레이스 : 공중 유닛, 비행기. 클로킹 (상대방에게 보이지 않음)
wraith1 = Unit("레이스", 80, 5) # 체력 80, 공격력 5
print("유닛 이름 : {0}, 공격력 : {1}".format(wraith1.name, wraith1.damage)) # 멤버변수 접근
# 마인드 컨트롤 : 상대방 유닛을 내 것으로 만드는 것 (빼앗음)
wraith2 = Unit("빼앗은 레이스", 80, 5)
wraith2.cloaking = True # 빼앗은 레이스만을 위한 특별한 멤버변수 정의
if wraith2.cloaking == True: # 클로킹 상태라면?
print("{0}는 현재 클로킹 상태입니다.".format(wraith2.name))
# 에러 발생
# if wraith1.cloaking == True: # 우리가 만든 레이스 클로킹 여부
# print("{0}는 현재 클로킹 상태입니다.".format(wraith1.name))
4. 메소드
: 메소드는 클래스 내에서 정의되는 함수입니다. 클래스에서 여러 개의 메소드를 정의할 수 있으며, 일반 함수와 다른 점이라면 메소드는 전달값을 정의하는 부분 처음에 self 를 적어준다는 점, 그리고 메소드 내에서 self. 를 통해 클래스 멤버변수에 접근 가능하다는 점입니다.
class AttackUnit: #공격유닛
def __init__(self,name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
def attack(self,location):
print(f"{self.name} : {location} 방향으로 적군을 공격 합니다. [공격력 {self.damage}]")
위에서 공격을 나타내는 attack이라는 메소드를 정의했습니다. 이 때 유닛 이름과 공격력은 이미 클래스 객체의 멤버 변수로 정의되어 있기 때문에 자기 자신을 의미하는 self. 을 쓰고, 공격 방향은 명령을 받을 때마다 달라질 수 있으므로 멤버 변수가 아닌 전달값을 사용하기 위해 self. 없이 쓴다는 점 주의해주셔야 합니다.
다음으로는 공격에 대한 대가로 데미지를 입는 메소드를 정의해보겠습니다. 공격받아서 hp가 0이하로 떨어진 유닛에 대해선 파괴되었다는 문장도 추가했습니다.
class AttackUnit:
... # __init__() 생략
... # attack() 생략
def damaged(self, damage): # damage 만큼 유닛 피해
print("{0} : {1} 데미지를 입었습니다.".format(self.name, damage)) # 데미지 정보 출력
self.hp -= damage # 유닛의 체력에서 전달받은 damage 만큼 감소
print("{0} : 현재 체력은 {1} 입니다.".format(self.name, self.hp)) # 남은 체력 출력
if self.hp <= 0: # 남은 체력이 0 이하이면?
print("{0} : 파괴되었습니다.".format(self.name)) # 유닛 파괴 처리
이제 만든 공격유닛 클래스를 활용하여 파이어뱃(화염방사기)이 공격하고, 데미지 입는 걸 표현해보겠습니다.
#파이어뱃 : 공격 유닛, 화염방사기.
firebat1 = AttackUnit("파이어뱃",50,16)
firebat1.attack("5시")
#공격 2번 받는다고 가정
firebat1.damaged(25)
firebat1.damaged(25)
5. 상속
: 클래스에는 상속이라는 개념이 있어서 공통되는 부분은 코드를 중복으로 적지 않고도 재사용을 할 수 있습니다.
스타크래프트에서 공격력이 없는 유닛인 메딕을 생성하고자합니다. 그래서 유닛 클래스에서 damage를 빼고 사용해보았습니다.
#일반 유닛
class Unit:
def __init__(self,name, hp):
self.name = name
self.hp = hp
그런데 위에서 만든 공격유닛과 일반 유닛 클래스의 공통부분(name,hp) 가 있는 걸 볼 수 있고 이 부분은 "상속"이라는 개념으로 채울 수 있습니다.
#일반 유닛
class Unit:
def __init__(self,name, hp):
self.name = name
self.hp = hp
#공격 유닛
class AttackUnit(Unit):
def __init__(self,name, hp, damage):
Unit.__init__(self,name,hp)
self.damage = damage
def attack(self,location):
print(f"{self.name} : {location} 방향으로 적군을 공격 합니다. [공격력 {self.damage}]")
def damaged(self,damage):
print(f"{self.name} : {damage} 데미지를 입었습니다.")
self.hp -=damage
print(f"{self.name} : 현재 체력은 {self.hp} 입니다.")
if self.hp <= 0:
print(f"{self.name} : 파괴되었습니다.")
6. 다중 상속
: 다른 클래스들로부터 상속을 다중으로 사용할 수 있다.
스타크래프트에는 레이스 외에도 드랍십이라는 유닛이 있습니다. 이 유닛은 날아다니면서 , 공격력은 가지고 있지는 않습니다.
날아다니는 것을 표현하기 위한 클래스를 우선 만들어 보겠습니다.
#날 수 있는 기능을 가진 클래스
class Flyable:
def __init__(self,flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print(f"{name} : {location} 방향으로 날아갑니다. [속도 {self.flying_speed}]")
또 다른 공중유닛으로 발키리라는 유닛이 있습니다. 이 유닛은 날아다니며, 공중유닛만 공격할 수 있습니다. 그럼 발키리를 찍어내기 위한 공중 공격유닛 클래스를 만들어보겠습니다.
#공중 공격 유닛 클래스
class FlyableAttackUnit(AttackUnit,Flyable):
def __init__(self,name,hp,damage,flying_speed):
AttackUnit.__init__(self,name,hp,damage)
Flyable.__init__(self,flying_speed)
#발키리 : 공중 공격 유닛, 한번에 14발 미사일 발사.
valkyrie = FlyableAttackUnit("발키리",200,6,5)
valkyrie.fly(valkyrie.name,"3시")
위와 같이 공격유닛 클래스에서 이름, 체력, 데미지변수를 상속받고 , 공중유닛 클래스에서 비행속도 변수를 상속받아 클래스를 만들었습니다. 발키리를 공중공격유닛 클래스를 이용해 찍어내면 잘 나오는 걸 볼 수있습니다.
마지막으로 클래스간에 상속을 정리하면 위 그림과 같습니다.
오늘은 클래스의 앞부분을 정리해봤습니다. 내용이 정말 많지만 예시와함께하니 재밌고 쓰임새가 많아서 좋습니다! ㅎㅎ
내일은 뒷부분 마저 정리하겠습니다.
*본 포스팅은 유튜브 '나도코딩' 강의를 듣고 작성하였습니다.
특별히 긴 강의를 인프런이라는 사이트에서 파트별로 나눠서 제공해줘서 손쉽게 접할 수 있었습니다. 아래 링크 첨부하겠습니다.
참고자료
'프로그래밍 공부 > Python' 카테고리의 다른 글
[파이썬 기초 6-2강] 클래스(메소드 오버라이딩, suepr, pass , 스타크래프트 진행) + 부동산 프로그램 작성 (0) | 2021.04.29 |
---|---|
[Python] 타입 힌팅(Type Hinting) 이란? (0) | 2021.04.21 |
[파이썬 기초 5강] 입출력(표준입출력, 다양한 출력포맷, 파일입출력, pickle, with) + 업무자동화_ 보고서 50개 만들기 (0) | 2021.03.15 |
[파이썬 기초 4강] 함수(전달값과 반환값, 기본값 ,가변인자, 지역변수와 전역변수) + 성별 적정체중 예측 (0) | 2021.03.11 |
[파이썬 기초 3강] 제어문(if문, for문,while문, continue,break, 한줄for문 ) + cocoa 택시 매칭방법 (2) | 2021.02.18 |