지난 글에 이어서 객체 지향을 사용한 Python 프로그래밍 방법에 대해 알아보겠습니다.
객체 지향 프로그래밍이란?
OOP(Object Oriented Programming)라고도 하는 객체지향 프로그래밍이란 프로그래밍 방법론이라고 생각하시면 됩니다. 기존에는 데이터 선언하고 데이터를 처리하는 함수들로 프로그램이 구성되었다면, 객체지향 프로그래밍에서는 프로그램을 객체(object)로 나누고 이 객체들의 상호작용으로 프로그램을 구성시킨 방법이라고 할 수 있습니다. 기존에는 함수를 선언하면 복사해서 재사용할 수 없지만, 객체지향 프로그래밍에서는 여러 번 복사해서 재사용할 수 있다는 장점이 있습니다.
여기서 객체는 데이터뿐만 아니라 데이터를 처리하는 함수인 메소드도 포함합니다. 즉, 객체는 데이터와 메소드의 집합이라고 보시면 됩니다.
객체지향 프로그래밍은 다음과 같은 장단점이 있습니다.
장점
- 코드 재사용이 용이
- 코드 유지보수 용이
단점
- 느린 처리 속도
- 프로그램의 용량이 커짐
그러면 본격적으로 객체지향 프로그래밍에 대해 알아보기 전에 클래스(class)와 객체(object)에 대해 알아봅시다.
Python 클래스와 객체
클래스는 객체를 만드는 틀이라고 보시면 됩니다. 하나의 틀로 여러 개의 상품을 만들 수 있듯이 클래스를 하나 지정하면 그 클래스로 여러 객체를 생성할 수 있습니다. 다음의 예시를 봅시다.
a = 0
b = 0
def plus_a(num) :
global a
a = a + num
return a
def plus_b(num) :
global b
b = b + num
return b
print(plus_a(14))
print(plus_a(23))
print(plus_b(3))
print(plus_b(5))
>> 14
>> 37
>> 3
>> 8위의 예시는 변수 a, b를 선언하고 각각에 대한 빼기 연산 함수를 정의했습니다. 만약 변수가 늘어난다면 그에 대한 함수가 점점 늘어날 겁니다. 그러면 불필요한 반복 작업이 늘어나겠죠?? 클래스와 객체를 활용해 이를 줄일 수 있습니다.
class Cal :
result = 0
def add(self, num) :
self.result = self.result + num
return self.result
a = Cal()
b = Cal()
print(a.add(14))
print(a.add(23))
print(b.add(3))
print(b.add(5))
>> 14
>> 37
>> 3
>> 8위의 코드를 보시면 Cal이라는 클래스를 선언한 것을 볼 수 있습니다, 이것이 하나의 틀입니다. 그래서 이 Cal이라는 틀로 a, b라는 객체를 만들었습니다. 객체 또는 인스턴스라고도 부르면 됩니다.
그러면 객체지향 프로그래밍의 시작인 클래스에 대해 더 자세히 알아봅시다.
Python 클래스에 대하여
먼저 클래스를 선언하는 방법은 다음과 같습니다.
class Name :
#클래스의 함수들 입력클래스의 이름을 정하고 함수인 메소드를 입력해 주면 됩니다. 앞에서 본 Cal을 완성해 볼까요?? 우선 Cal이라는 클래스에는 더하기, 빼기, 곱하기, 나누기라는 메소드들이 있을 것입니다.
class Cal :
#값 초기화
result = 0
def plus(self, num) :
self.result = self.result + num
return self.result
def minus(self, num) :
self.result = self.result - num
return self.result
def multiple(self, num) :
self.result = self.result * num
return self.result
def div(self, num) :
self.result = self.result / num
return self.resultCal이라는 클래스를 선언하고 result라는 변수를 초기화한 뒤 더하기, 빼기, 곱하기, 나누기 메소드들을 선언했습니다. 여기서 ‘self’는 자기 자신을 표현한 것이라고 이해하시면 되겠습니다.
그렇다면 하나의 클래스에는 하나의 변수만 가져야 할까요?? 그건 아닙니다.
class grade :
#필드
name = ""
score = 0
#메소드
def plus(self, num) :
self.score = self.score + num
return self.score
def minus(self, num) :
self.score = self.score - num
return self.scoregrade라는 클래스에는 학생 이름과 점수를 변수로 선언했습니다. 그렇다면 이 틀(클래스)로 상품(객체)을 만들어봅시다.
Python 객체 만들기
위의 코드에 이어서 다음과 같은 코드를 작성해 봅시다.
class grade :
#필드
name = ""
score = 0
#메소드
def plus(self, num) :
self.score = self.score + num
return self.score
def minus(self, num) :
self.score = self.score - num
return self.score
student1 = grade()
student2 = grade()
student3 = grade()
student1.name = "철수"
student2.name = "영희"
student3.name = "민수"
student1.score = 0
student2.score = 0
student3.score = 0
student1.score = 73
student2.score = 89
student3.score = 91
print(student1.name, student1.score)
print(student2.name, student2.score)
print(student3.name, student3.score)
>> 철수 73
>> 영희 89
>> 민수 91객체 3개를 만들어 각각의 객체에 값을 입력해 주었습니다. 그러면 이제 클래스에 선언한 메소드들을 활용해 봅시다.
class grade :
#필드
name = ""
score = 0
#메소드
def plus(self, num) :
self.score = self.score + num
return self.score
def minus(self, num) :
self.score = self.score - num
return self.score
student1 = grade()
student2 = grade()
student3 = grade()
student1.name = "철수"
student2.name = "영희"
student3.name = "민수"
student1.score = 0
student2.score = 0
student3.score = 0
student1.score = 73
student2.score = 89
student3.score = 91
student1.plus(5)
student2.minus(2)
student3.plus(3)
print(student1.name, student1.score)
print(student2.name, student2.score)
print(student3.name, student3.score)
>> 철수 78
>> 영희 87
>> 민수 94위의 예시를 보면 클래스를 활용해서 코드를 간결하게 작성할 수 있다는 것을 확인할 수 있습니다.
정리해 보자면 클래스, 객체 활용 순서는 다음과 같습니다.
- 클래스 선언: 클래스 이름, 필드, 메소드 선언
- 객체(인스턴스) 생성
- 필드나 메소드 활용
생성자
grade 클래스를 보면 중간에 score를 일일이 초기화시켜 주는 과정이 있는데요, 클래스 안에 생성자를 설정함으로써 score의 초깃값을 설정해 줄 수 있습니다. 생성자는 init으로 선언할 수 있습니다.
class grade :
#생성자
def __init__(self) :
self.name = ""
self.score = 0
#메소드
def plus(self, num) :
self.score = self.score + num
return self.score
def minus(self, num) :
self.score = self.score - num
return self.score
student1 = grade()
student2 = grade()
student3 = grade()
student1.name = "철수"
student2.name = "영희"
student3.name = "민수"
student1.score = 73
student2.score = 89
student3.score = 91위의 코드를 보면 필드를 선언하지 않은 것을 확인할 수 있습니다. 일반적으로 클래스를 선언할 때는 필드를 선언하는 것이 아니라 생성자를 통해 필드를 선언한다고 합니다.
그렇다면 인스턴스를 생성할 때 초깃값을 입력할 수 없을까요?? 생성자를 만들 때 매개 변수를 사용하면 가능합니다.
class grade :
#생성자
def __init__(self, val1, val2) :
self.name = val1
self.score = val2
#메소드
def plus(self, num) :
self.score = self.score + num
return self.score
def minus(self, num) :
self.score = self.score - num
return self.score
student1 = grade("철수",73)
student2 = grade("영희",89)
student3 = grade("민수",91)
print(student1.name, student1.score)
print(student2.name, student2.score)
print(student3.name, student3.score)클래스 변수와 인스턴스 변수의 차이
지금까지 봐온 예시에서 선언된 변수들은 모두 인스턴스 변수입니다. ‘grade’라는 클래스를 통해 ‘student’라는 인스턴스를 만들고, 그 인스턴스에는 ‘name’과 ‘score’라는 변수가 있었죠. student1.name과 student2.name은 다른 변수인 겁니다. 이러한 변수들은 인스턴스를 선언해야 만들어지고 메모리에 할당되게 됩니다.
인스턴스에 변수가 있듯이 클래스에도 변수가 존재합니다. 클래스 변수는 클래스 안에 할당되는데요, 그렇기 때문에 모든 인스턴스가 이 클래스 변수를 공유하게 됩니다.
참고: 위키독스