자료구조 트리를 공부하면서 이진트리 탐색 구현 부분을 공부하고 있는데, 파이썬에서 클래스의 개념을 한번 짚고 넘어가야할 것 같아서 이 글을 쓰게되었다.
클래스가 필요한 이유
클래스를 쓰지 않아도 프로그램을 만들 수 있지만, 클래스를 사용하면 개발자에게 좋은 점이 많다.
만약 하나의 프로그램에서, 간단한 요리를 만드는 프로그램을 만든다고 가정한다.
첫번째 요리를 레시피대로 만드는 함수 1이 있다고 하고, 함수에 들어가는 재료와, 요리 결과물을 담는 결과(그릇)가 있다고 가정한다.
만약 이때, 첫번째 요리를 함과 동시에 두번째 요리로 요리 재료를 조금만 바꿔서 또 다른 요리를 만든다고 했을때,
프로그램에는 함수에 들어가는 또 다른 재료와, 재료가 바뀐 결과물을 담는 결과(그릇)가 하나 더 있어야 하고
동시에 요리를 하지만 두번째 결과물(그릇)에 요리를 담아야 하므로 요리를 레시피대로 만드는 함수 2가 더 필요하다.
만약 이때, 하나의 프로그램에서 10가지 각각 다른 요리를 만들어야 한다면?
요리에 필요한 함수와 결과(그릇)을 일일이 하나씩 만들어줘야 한다. 그리고 레시피도 조금씩 변경되면 더 복잡해질 것이다.
이때 필요한 것이 클래스이다.
cooking bowl1 = 0
cooking bowl2 = 0
def recepe1(num):
global cooking bowl1
cooking bowl1 += num
return cooking bowl1
def recepe2(num):
global cooking bowl2
cooking bowl2 += num
return cooking bowl2
print(add1(3))
print(add1(4))
print(add2(3))
print(add2(7))
클래스 사용전
class Cooking:
def __init__(self):
self.cookingBowl = 0
def recepe1(self, num):
self.cookingBowl += num
cookingBowl self.cookingBowl
# 기능 추가시 해당 위치에 함수 추가
cookingBowl1 = Cooking() # 객체
cookingBowl2 = Cooking()
print(cookingBowl1.recepe1(3))
print(cookingBowl1.recepe1(4))
print(cookingBowl2.recepe1(3))
print(cookingBowl2.recepe1(7))
클래스 사용후
클래스 내부 함수를 메서드라고 부른다.
클래스로 만든 객체의 객체변수는 다른 객체의 객체변수에 상관없이 독립적인 값을 유지한다.
class FourCal:
def __init__(self, first, second): # 아래의 setdata와 똑같지만, 생성자이므로 객체 생성시 자동으로 호출된다는 차이가 존재함
self.first = first
self.second = second
def setdata(self, first, second): # 메서드
# 파이썬 메서드에서 첫 번째 매개변수 이름은 관례적으로 self를 사용한다.
# 객체 호출시, 호출한 객체 자신이 전달되므로 self를 사용한다.
self.first = first
self.second = second
def add(self):
sum = self.first + self.second
return sum
def sub(self):
sum = self.first - self.second
return sum
def mul(self):
sum = self.first * self.second
return sum
def div(self):
sum = self.first / self.second
return sum
# 상속
# FourCal 클래스를 상속하는 MoreFourCal클래스이다.
# 기존 클래스를 수정하지 않고 상속을 이용하는 이유는?
# 기존 클래스가 라이브러리 형태로 제공되거나 수정이 불가한 상황일 때 사용한다.
class MoreFourCal(FourCal):
def pow(self):
result = self.first ** self.second
return result
class SafeFourCal(FourCal):
def div(self):
if self.second == 0:
return 0
else:
return self.first / self.second
# 부모 클래스에 있는 메서드를 같은 이름으로 다시 만드는 것을
# 메서드 오버라이딩 이라고 한다.
# 이럴 경우 기존 부모 클래스의 div함수가 아닌 오버라이딩한 메서드가 호출된다.
class Friend:
lastname = "배" # 클래스 변수: 클래스 안에 변수를 선언하여 생성
classVar = Friend()
name = classVar.lastname
print('name: ',name)
Friend.lastname = "이"
name = classVar.lastname
print('name: ',name)
# 객체 변수와 다르게 클래스 변수는 모든 객체에 공유된다.
# 클래스 변수와 같은 이름의 객체 변수 생성이 가능하다.
classVar.lastname = "최"
name2 = classVar.lastname
print('name2: ', name2)
print('name: ',name)
# 기존의 classVar 클래스의 lastname과는 상관 없다.
# 즉, classVar 클래스의 클래스 변수 lastname은 변하지 않았음
#a = FourCal() # 생성자를 만든 후에는 안에 인자를 넣어줘야 값이 전달된다.
# a.setdata(4, 2)
a = FourCal(4, 2)
# 객체를 이용해 클래스의 메서드 호출 시 .연산자 사용
# FourCal클래스의 setdata메서드는 인자가 self, first, second로 3개임
# 그런데 왜 객체 a의 메서드 호출시에는 2개의 인자만 사용되어도 문제가 없는걸까?
# 객체 a가 setdata의 self로 자동으로 전달되기 때문이다.
# 만약 객체 생성시 초기값을 설정 해주지 않고, 객체로 다른 메서드를 호출한다면
# 오류가 발생한다.
# 이를 방지하기 위해 생성자를 구현해두는 것이 안전하다.
# 생성자는 객체가 만들어질 때 자동으로 호출되는 메서드를 말한다.
# 파이썬 메서드 명으로 __init__을 사용하면 해당 메서드는 생성자가 된다.
c = a.add()
print(c)
b = MoreFourCal(4, 2) # 클래스는 상속받은 FourCal 클래스의 모든 기능을 사용할 수 있다.
d = b.add()
print(d)
'Python' 카테고리의 다른 글
[Python] 컴프리헨션(comprehension) (0) | 2024.04.08 |
---|---|
[Python]각종 함수 (0) | 2024.04.05 |
[5주차]9장 이진트리 (0) | 2024.03.21 |
[4주차]8장 해시 (0) | 2024.01.30 |
[3주차]7장 큐 (0) | 2024.01.30 |