250x250
반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Retry
- API
- hadoop
- session 유지
- 공분산
- UDF
- flask
- Airflow
- spark udf
- TensorFlow
- GenericGBQException
- correlation
- chatGPT
- youtube data
- tensorflow text
- 유튜브 API
- Counterfactual Explanations
- grad-cam
- gather_nd
- requests
- 상관관계
- airflow subdag
- XAI
- API Gateway
- integrated gradient
- subdag
- login crawling
- GCP
- top_k
- BigQuery
Archives
- Today
- Total
데이터과학 삼학년
Inheritance and Subclass (상속과 서브 클래스) 본문
반응형
파이썬에서 부모클래스를 상속받는 서브 클래스의 개념에 대해 알아본다.
일단 class를 만드는 가장 큰 목적은 붕어빵을 찍어내는 틀처럼 같은 속성을 가지는 데이터 타입 생성에 대해 반복되는 코드를 줄이고, 필요에 따라 간략한 수정을 가능하도록 하는데 있다.
즉 class를 이용하면 불필요한 재활용 코드를 줄이고, 보다 깔끔하고, 명확하게 코드를 작성할 수 있다.
# -*- coding: utf-8 -*-
class Unit(object):
def __init__(self, rank, size, life):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
class Goblin(Unit):
pass
goblin_1 = Goblin('병사', 'Small', 100)
goblin_1.show_status()
==================
이름: Goblin
등급: 병사
사이즈: Small
라이프: 100
이처럼 Goblin 이라는 class는 Unit class를 상속받아 Unit에서 지정한 method를 모두 활용하여 쓸 수 있다.
단 Goblin은 부모 클래스인 Unit을 참조하여 실행된다.
여기서 Goblin class에서 __init__ 정보를 더 추가하고 싶으면 어떻게 할까? --> 메서드 오버라이드
이때는 아래 코드처럼 일일히 다시 메서드를 만들어 줄 수도 있지만....
이 방법은 클래스를 사용하는 의미가 전혀없음
# -*- coding: utf-8 -*-
class Unit(object):
def __init__(self, rank, size, life):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
class Goblin(Unit):
def __init__(self, rank, size, life, attack_type):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
self.attack_type = attack_type
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
print('공격 타입: {}'.format(self.attack_type))
goblin_1 = Goblin('병사', 'Small', 100, '근접 공격')
goblin_1.show_status()
==================
이름: Goblin
등급: 병사
사이즈: Small
라이프: 100
공격 타입: 근접 공격
이런 경우에는 super() 함수를 사용하여 이미 부모 클래스에서 정의된 메소드를 호출하여 같은 코드를 반복하지 않도록 한다. super() 함수를 사용하여 중복된 코드를 줄여 보겠습니다.
1. super(<자신의 class명>, self).<부모클래스에서 불러올메서드명>
2. super().<부모클래스에서 불러올메서드명>
두가지 방법 모두 사용 가능
# -*- coding: utf-8 -*-
class Unit(object):
def __init__(self, rank, size, life):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
class Goblin(Unit):
def __init__(self, rank, size, life, attack_type):
super(Goblin, self).__init__(rank, size, life)
self.attack_type = attack_type
def show_status(self):
super(Goblin, self).show_status()
print('공격 타입: {}'.format(self.attack_type))
goblin_1 = Goblin('병사', 'Small', 100, '근접 공격')
goblin_1.show_status()
# -*- coding: utf-8 -*-
class Unit(object):
def __init__(self, rank, size, life):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
class Goblin(Unit):
# damage 속성 추가
def __init__(self, rank, size, life, attack_type, damage):
super(Goblin, self).__init__(rank, size, life)
self.attack_type = attack_type
self.damage = damage
def show_status(self):
super(Goblin, self).show_status()
print('공격 타입: {}'.format(self.attack_type))
# 오버라이드 메소드
print ('데미지: {}'.format(self.damage))
# 공격 메소드 추가
def attack(self):
print('[{}]이 공격합니다! 상대방 데미지({})'.format(self.name, self.damage))
class SphereGoblin(Goblin):
def __init__(self, rank, size, life, attack_type, damage, sphere_type):
super(SphereGoblin, self).__init__(rank, size, life, attack_type, damage)
self.sphere_type = sphere_type
def show_status(self):
super(SphereGoblin, self).show_status()
print('창 타입: {}'.format(self.sphere_type))
sphere_goblin_1 = SphereGoblin('병사', 'Small', 100, '레인지 공격', 10, '긴 창')
sphere_goblin_1.show_status()
========================
이름: SphereGoblin
등급: 병사
사이즈: Small
라이프: 100
공격 타입: 레인지 공격
데미지: 10
창 타입: 긴 창
이렇게 만들수 있다.
hero와 같이 새로 class를 만들거나 에러관련 메서드도 추가하면 아래와 같이 서브 클래스를 응용할 수 있다.
# -*- coding: utf-8 -*-
class Unit(object):
def __init__(self, rank, size, life):
self.name = self.__class__.__name__
self.rank = rank
self.size = size
self.life = life
def show_status(self):
print('이름: {}'.format(self.name))
print('등급: {}'.format(self.rank))
print('사이즈: {}'.format(self.size))
print('라이프: {}'.format(self.life))
class Goblin(Unit):
# damage 속성 추가
def __init__(self, rank, size, life, attack_type, damage):
super(Goblin, self).__init__(rank, size, life)
self.attack_type = attack_type
self.damage = damage
def show_status(self):
super(Goblin, self).show_status()
print('공격 타입: {}'.format(self.attack_type))
# 오버라이드 메소드
print ('데미지: {}'.format(self.damage))
# 공격 메소드 추가
def attack(self):
print('[{}]이 공격합니다! 상대방 데미지({})'.format(self.name, self.damage))
class SphereGoblin(Goblin):
def __init__(self, rank, size, life, attack_type, damage, sphere_type):
super(SphereGoblin, self).__init__(rank, size, life, attack_type, damage)
self.sphere_type = sphere_type
def show_status(self):
super(SphereGoblin, self).show_status()
print('창 타입: {}'.format(self.sphere_type))
class Hero(Unit):
def __init__(self, rank, size, life, goblins=None):
super(Hero, self).__init__(rank, size, life)
if goblins is None:
self.goblins = []
else:
self.goblins = goblins
def show_own_goblins(self):
num_of_goblins = len([x for x in self.goblins if isinstance(x, Goblin)])
num_of_sphere_goblins = len([x for x in self.goblins if isinstance(x, SphereGoblin)])
print('현재 영웅이 소유한 고블린은 {}명, 창 고블린은 {}명입니다.'.format(num_of_goblins, num_of_sphere_goblins))
def make_goblins_attack(self):
for goblin in self.goblins:
goblin.attack()
def add_goblins(self, new_goblins):
for goblin in new_goblins:
if goblin not in self.goblins:
self.goblins.append(goblin)
else:
print('이미 추가된 고블린입니다.')
def remove_goblins(self, old_goblins):
for goblin in old_goblins:
try:
self.goblins.remove(goblin)
except:
print('소유하고 있지 않은 고블린입니다.')
# 고블린 오브젝트 생성
goblin_1 = Goblin('병사', 'Small', 100, '근접 공격', 15)
goblin_2 = Goblin('병사', 'Small', 100, '근접 공격', 15)
sphere_goblin_1 = SphereGoblin('병사', 'Small', 100, '레인지 공격', 10, '긴 창')
# 영웅 오브젝트 생성 후, 고블린 오브젝트 할당
hero_1 = Hero('영웅', 'Big', 300, [goblin_1, goblin_2, sphere_goblin_1])
# 새로운 고블린 생성
goblin_3 = Goblin('병사', 'Small', 100, '근접 공격', 20)
sphere_goblin_2 = SphereGoblin('병사', 'Small', 100, '레인지 공격', 5, '긴 창')
print('# 새로운 고블린 추가 전')
hero_1.show_own_goblins()
hero_1.make_goblins_attack()
# 새로운 고블린 추가
hero_1.add_goblins([goblin_3, sphere_goblin_2])
print('\n# 새로운 고블린 추가 후')
hero_1.show_own_goblins()
hero_1.make_goblins_attack()
# 추가한 고블린 삭제
hero_1.remove_goblins([goblin_3, sphere_goblin_2])
print('\n# 추가한 고블린 삭제 후')
hero_1.show_own_goblins()
hero_1.make_goblins_attack()
# 영웅에게 소유되지 않은 고블린 생성
goblin_4 = Goblin('병사', 'Small', 100, '근접 공격', 20)
# 이미 소유한 고블린 추가
print('\n# 에러 메세지 발생')
hero_1.add_goblins([goblin_1])
hero_1.remove_goblins([goblin_4])
====================================
# 새로운 고블린 추가 전
현재 영웅이 소유한 고블린은 3명, 창 고블린은 1명입니다.
[Goblin]이 공격합니다! 상대방 데미지(15)
[Goblin]이 공격합니다! 상대방 데미지(15)
[SphereGoblin]이 공격합니다! 상대방 데미지(10)
# 새로운 고블린 추가 후
현재 영웅이 소유한 고블린은 5명, 창 고블린은 2명입니다.
[Goblin]이 공격합니다! 상대방 데미지(15)
[Goblin]이 공격합니다! 상대방 데미지(15)
[SphereGoblin]이 공격합니다! 상대방 데미지(10)
[Goblin]이 공격합니다! 상대방 데미지(20)
[SphereGoblin]이 공격합니다! 상대방 데미지(5)
# 추가한 고블린 삭제 후
현재 영웅이 소유한 고블린은 3명, 창 고블린은 1명입니다.
[Goblin]이 공격합니다! 상대방 데미지(15)
[Goblin]이 공격합니다! 상대방 데미지(15)
[SphereGoblin]이 공격합니다! 상대방 데미지(10)
# 에러 메세지 발생
이미 추가된 고블린입니다.
소유하고 있지 않은 고블린입니다.
728x90
반응형
LIST
'Python' 카테고리의 다른 글
First Class Function (일급 함수) (0) | 2020.04.13 |
---|---|
Magic method (매직 메서드) (0) | 2020.04.06 |
Instance method, Class method, Static method (1) | 2020.04.04 |
문자열 포맷팅 (% operator, str.format, f-string) (0) | 2020.04.02 |
property (getter, setter) (0) | 2020.03.23 |
Comments