Python 기초 5

Lilmeow·2023년 4월 13일
0

Python Basic

목록 보기
5/7
post-thumbnail

비효율적인 함수 호출

name = 'M'
hp = 40
damage = 5
print("name : {0}".format(name))
print('hp : {0}, damage : {1}\n'.format(hp, damage))
# name : M
# hp : 40, damage : 5

name2 = 'T'
hp2 = 150
damage2 = 35
print("name2 : {0}".format(name2))
print('hp2 : {0}, damage2 : {1}\n'.format(hp2, damage2))
# name2 : T
# hp2 : 150, damage2 : 35

def attack(name, location, damage):
    print('{0} : {1} attack [damage : {2}]'.format(name, location, damage))

attack(name, '1', damage)
attack(name2, '2', damage2)
# M : 1 attack [damage : 5]
# T : 2 attack [damage : 35]

Class

class Unit:
    def __init__(self, name, hp, damage): # __init__ : 파이썬에서 사용되는 생성자, 객체를 생성할 때 자동으로 호출됨
        self.name = name
        self.hp = hp
        self.damage = damage
        # name, hp, damage : 멤버 변수, class 내에서 정의된 변수, 초기화, 사용 등이 가능하다
        print('generate : {0}'.format(self.name))
        print('hp : {0}, damage : {1}'.format(self.hp, self.damage))
        
m1 = Unit('M', 40, 5) # Unit class의 객체 생성
m2 = Unit('M', 40, 5)
t1 = Unit('T', 150, 35)
# 똑같은 class에 대해서 서로 다른 객체들을 생성
# m1, m2, t1은 Unit class의 Instance라 한다
# generate : M
# hp : 40, damage : 5
# generate : M
# hp : 40, damage : 5
# generate : T
# hp : 150, damage : 35

w1 = Unit('W', 80, 5)
# generate : W
# hp : 80, damage : 5
print('generate : {0}, damage : {1}'.format(w1.name, w1.damage)) # 객체.멤버변수 : 멤버변수를 외부에서 접근할 수 있다
# generate : W, damage : 5

w2 = Unit('W_enemie', 80, 5)
# generate : W_enemie
# hp : 80, damage : 5
w2.ability = True # class에서 쓰이지 않은 변수에 대해서 외부에서 추가 가능하다, 단, 추가를 한 객체에 대해서만 변수 사용이 가능하다
if w2.ability == True:
    print('{0} : ability on'.format(w2.name))
# W_enemie : ability on

Method

class Unit:
    def __init__(self, name, hp, damage):
        self.name = name
        self.hp = hp
        self.damage = damage
        print('generate : {0}'.format(self.name))
        print('hp : {0}, damage : {1}'.format(self.hp, self.damage))

class AttackUnit:
    def __init__(self, name, hp, damage): # 객체 생성을 위해 입력받아야하는 값들
        self.name = name
        self.hp = hp
        self.damage = damage
        
    def attack(self, location): # method, 입력받고 동작
        print('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        # self를 사용하면 자기 자신만의 변수에 접근을 할 수 있다
        # self가 없다면 전달받은 값을 바로 쓰는 것
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))
            
fire1 = AttackUnit('F', 50, 16)
fire1.attack('5')
# F : to 5 attack [damage : 16]

fire1.damaged(25)
# F : 25 damaged
# F : current hp is 25
fire1.damaged(25)
# F : 25 damaged
# F : current hp is 0
# F : destroyed

상속

class Unit:
    def __init__(self, name, hp):
        self.name = name
        self.hp = hp

class AttackUnit(Unit): # Unit class(부모)의 멤버변수들을 상속받아 AttackUnit(자식)이라는 class를 만든다
    def __init__(self, name, hp, damage):
        Unit.__init__(self, name, hp) # Unit class에서 멤버변수를 상속 받는 법
        self.damage = damage
        
    def attack(self, location):
        print('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        # self를 사용하면 자기 자신만의 변수에 접근을 할 수 있다
        # self가 없다면 전달받은 값을 바로 쓰는 것
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))

다중 상속

# 여러 부모 class에서 상속 받는 것
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('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))
            
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed
        
    def fly(self, name, location):
        print('{0} : to {1} flying [speed : {2}]'.format(name, location, self.flying_speed))
        
class FlyableAttackUnit(AttackUnit, Flyable): # 단지 두개의 부모 클래스에서 상속만 받은 class
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, damage)
        Flyable.__init__(self, flying_speed)
        
v1 = FlyableAttackUnit('V', 200, 6, 5) # FlyableAttackUnit class의 객체 생성
v1.fly(v1.name, 3) # 객체.멤버변수 : V

Method Overriding의 필요성

class Unit:
    def __init__(self, name, hp, speed): # speed 추가
        self.name = name
        self.hp = hp
        self.speed = speed # speed 추가
        
    def move(self, location): # method 추가
        print('[unit move]')
        print('{0} : to {1} move [speed : {2}]'.format(self.name, location, self.speed))

class AttackUnit(Unit):
    def __init__(self, name, hp, speed, damage): # 상속 받기 때문에 speed 추가
        Unit.__init__(self, name, hp, speed) # 상속 받기 때문에 speed 추가
        self.damage = damage
        
    def attack(self, location):
        print('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))
            
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed
        
    def fly(self, name, location):
        print('{0} : to {1} flying [speed : {2}]'.format(name, location, self.flying_speed))
        
class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage) # flying_speed가 있으니 speed 값은 0을 준다
        Flyable.__init__(self, flying_speed)
        
vv1 = AttackUnit('VV', 80, 10, 20)
battle1 = FlyableAttackUnit('B', 500, 25, 3)

vv1.move('11') # unit에 따른 move와 fly를 구분 > method overriding을 사용하여 더 편리하게
# [unit move]
# VV : to 11 move [speed : 10]
battle1.fly(battle1.name, '7')
# B : to 7 flying [speed : 3]

Method Overriding

class Unit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        
    def move(self, location):
        print('[unit move]')
        print('{0} : to {1} move [speed : {2}]'.format(self.name, location, self.speed))

class AttackUnit(Unit):
    def __init__(self, name, hp, speed, damage):
        Unit.__init__(self, name, hp, speed)
        self.damage = damage
        
    def attack(self, location):
        print('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))
            
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed
        
    def fly(self, name, location):
        print('{0} : to {1} flying [speed : {2}]'.format(name, location, self.flying_speed))
        
class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage)
        Flyable.__init__(self, flying_speed)
        
    def move(self, location): # move() 함수 재정의 : method overriding
        print('[flying]')
        self.fly(self.name, location) # move method 안에서 멤버변수와 매개변수를 이용하여 fly method를 사용
        
vv1 = AttackUnit('VV', 80, 10, 20)
battle1 = FlyableAttackUnit('B', 500, 25, 3)

vv1.move('11')
# [unit move]
# VV : to 11 move [speed : 10]
battle1.move('7')
# [flying]
# B : to 7 flying [speed : 3]
vv1.move('11')
# [unit move]
# VV : to 11 move [speed : 10]

Pass

class Unit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        
    def move(self, location):
        print('[unit move]')
        print('{0} : to {1} move [speed : {2}]'.format(self.name, location, self.speed))
        
class BuildingUnit(Unit):
    def __init__(self, name, hp, location):
        pass # 일단 아무 것도 안하고 넘어가는 것
    
sup1 = BuildingUnit('S', 500, '7')
# (아무 변화 없음)

def start():
    print('start')
def over():
    pass
start()
# start
over()
# (아무 변화 없음)

Super

class Unit:
    def __init__(self, name, hp, speed):
        self.name = name
        self.hp = hp
        self.speed = speed
        
    def move(self, location):
        print('[unit move]')
        print('{0} : to {1} move [speed : {2}]'.format(self.name, location, self.speed))

class AttackUnit(Unit):
    def __init__(self, name, hp, speed, damage):
        Unit.__init__(self, name, hp, speed)
        self.damage = damage
        
    def attack(self, location):
        print('{0} : to {1} attack [damage : {2}]'.format(self.name, location, self.damage))
        
    def damaged(self, damage):
        print('{0} : {1} damaged'.format(self.name, damage))
        self.hp -= damage
        print('{0} : current hp is {1}'.format(self.name, self.hp))
        if self.hp <= 0:
            print('{0} : destroyed'.format(self.name))
            
class Flyable:
    def __init__(self, flying_speed):
        self.flying_speed = flying_speed
        
    def fly(self, name, location):
        print('{0} : to {1} flying [speed : {2}]'.format(name, location, self.flying_speed))
        
class FlyableAttackUnit(AttackUnit, Flyable):
    def __init__(self, name, hp, damage, flying_speed):
        AttackUnit.__init__(self, name, hp, 0, damage)
        Flyable.__init__(self, flying_speed)
        
    def move(self, location):
        print('[flying]')
        self.fly(self.name, location)
        
class BuildingUnit(Unit):
    def __init__(self, name, hp, location):
        # Unit.__init__(self, name, hp, 0) # speed : 0, 기존 상속 초기화
        super().__init__(name, hp, 0) # super() 사용, self는 입력 안함 > 다중 상속에서 문제 발생
        self.location = location
    
sup1 = BuildingUnit('S', 500, '7')

다중 상속에서의 Super

class Unit: # 이 class만 상속 받아 초기화됨
    def __init__(self):
        print('unit init')
        
class Flyable:
    def __init__(self):
        print('flyable init')
        
class FlyableUnit(Unit, Flyable): # 다중 상속을 받을 때, super를 사용하여 상속받은 생성자는 항상 맨 앞의 class(Unit)이다
    def __init__(self):
        super().__init__()
#         Unit.__init__(self)
#         Flyable.__init__(self) # 이 방법을 사용해야 두 class를 초기화할 수 있다
        
drop1 = FlyableUnit()
# unit init

0개의 댓글