"객체 지향 사고 프로세스"와 "인프런 - 우리를 위한 프로그래밍 : 파이썬 중급 (Inflearn Original)"를 참고하여 작성했습니다.
오늘부터는 객체 지향 프로그래밍에 대해서 조금씩 알아보고자 합니다. 저는 파이썬을 오래 사용해보지 않았습니다. 맨 처음에 공부할 때 클래스에 대한 기억은 그렇게 좋지 않았습니다. "__init__은 뭐지? self는 뭐지? 데코레이터는 뭐지? 어색한 용어들이 가득했기에 나중에 차차 알게 되겠지." 하면서 넘겼습니다. 하지만, 이제는 넘기지 말아야 할 때가 된 것 같다는 생각에 마음잡고 책과 인강의 도움을 받으며, 객체 지향에 대해서 알아보려고 합니다. 읽으시면서 약간 이상하다고 생각되는 부분이 있다면 언제든지 말씀해주시면 감사하겠습니다!
작성된 내용은 다음과 같습니다.
-
객체에 대한 설명
-
객체가 파이썬에서는 어떻게 적용되는가?
-
객체 지향 프로그래밍의 장점
1. 객체
객체 지향을 알아보기 이전에 가장 먼저 객체는 무엇인지 알아보고자 합니다. 객체는 어떤 것이든지 소프트웨어 세상에 구현하고 싶은 대상을 말합니다. 예를 들면, 사람은 눈 색깔, 나이, 키처럼 개인마다 가지고 있는 속성(attributes)이 있으며, 걷기, 말하기, 공부하기 등과 같은 행위(behaviors)를 합니다. 이처럼 객체는 속성과 행위라는 두가지 성분으로 정의할 수 있습니다. 다른 예를 하나 더 들어볼까요? 핸드폰을 예를 들어보겠습니다. 핸드폰은 제조사, 가격, 기종, 색상과 같은 속성을 가지고 있으며, 전화 걸기, 전화받기, 어플 실행하기, 음악 듣기와 같은 많은 행위를 할 수 있습니다. 생물, 사물과 상관없이 속성과 행위를 가지는 것들은 객체라고 표현할 수 있습니다.
파이썬은 객체의 속성과 행위를 어떻게 표현할까요? 바로, 클래스를 통해서 구현할 수 있습니다. 클래스에는 __init__이라는 객체를 초기화할 때 호출되는 메소드가 존재합니다. 여기에는 객체에 포함되어야 할 속성들이 작성되어 있습니다. 그렇다면 행위는 어디에 표현하고 있을까요? 클래스 내부에 함수 형태를 이용해서 표현할 수 있습니다. 흔히, 클래스를 표현할 때, 붕어빵 틀이라는 표현을 많이 사용합니다. 붕어빵 틀에서 만들어진 붕어빵을 인스턴스라고 표현합니다. 인스턴스는 클래스를 이용해서 이미 구현된 구체적인 실체를 뜻합니다. 한번 예시를 통해서 알아봅시다.
class Person(object):
def __init__(self, name, age, gender): #속성(attributes)
self._name = name
self._age = age
self._gender = gender
def introduce_myself(self): #행위(behavior)
return f"My name is {self._name}. I'm {self._age} years old."
person = Person("Kim", "20", "Male") # 객체 생성
print(person.introduce_myself()) # My name is Kim. I'm 20 years old.
예시 코드를 보시면, 가장 먼저 클래스를 선언하고 어떤 객체명을 Person이라고 지정했습니다. 그 밑에 함수(메서드)가 2개가 있습니다. 첫 번째에 있는 __init__ 메서드는 변수로 name, age, gender를 받습니다. 여기서 "이상하다. 분명, self라는 것도 있는데, 쟤는 뭐지?"라고 생각하실 수 있습니다. 다음에 다루게 될 내용에는 메서드의 종류를 설명할 예정입니다만 간략히 설명드리면, 그중에 self가 들어있는 것은 인스턴스와 연관된 메서드, 변수라고 부릅니다. 인스턴스는 각자의 정보를 가지고 있어야 하며, 다른 사람의 정보와 섞이면 안 됩니다. 그래서 자신의 이름을 저장하기 위해서 인스턴스 변수에 정보를 저장합니다. 더 자세한 이야기는 다음에 해보도록 하겠습니다. 두 번째로는 자기를 소개하는 함수(행위)를 만들어 봤습니다. 함수는 self에 대한 정보를 받아서 이름과 나이를 소개하도록 만들었습니다. 이러한 방식을 통해서 파이썬에서는 구현해볼 수 있습니다.
2. 객체지향 프로그래밍 장점
그렇다면 객체 지향 프로그래밍은 어떠한 장점이 있어서 사용되고 있을까요? 아래의 코드를 보면서 한번 알아봅시다.
# 일반적인 코딩
cellphone_company_1 = 'Apple'
cellphone_detail_1 = [{'color':'white'},{'price':'1000'}]
cellphone_company_2 = 'samsung'
cellphone_detail_2 = [{'color':'black'},{'price':'1000'}]
핸드폰 중고매장에서 중고폰을 관리하기 위해서 위와 같은 형태로 관리했다고 합시다. 그러면, 어떤 문제가 생길까요? 매번 중고폰이 들어올 때마다 위의 코드로 정보를 입력해줘야 합니다. 데이터가 많아지면, 관리하기가 쉽지 않을 것입니다. 그럼 이번에는 리스트 구조로 변경해보겠습니다.
# 리스트 구조
cellphone_company_list = ['Apple','samsung']
cellphone_detail_list = [{'color':'white','price':'1000'}, {'color':'black','price':'1000'}]
위에서 했던 코드양보다는 확실하게 줄었습니다. 또한 새로운 중고폰이 들어오면, append()를 통해서 넣어줄 수 있어서 편한 장점이 있습니다. 하지만, 중간에 중고폰이 팔렸다고 해봅시다. 그러면, 접근하기 위해서는 인덱스를 알아야 제거할 수 있다는 단점이 있습니다. 그러면 딕셔너리 구조로 만들어보면 어떻게 될까요?
# 리스트 구조
cellphone_dict = [
{'cellphone_company': 'Apple','cellphone_detail':{'color':'white','price':'1000'}}
{'cellphone_company': 'samsung','cellphone_detail':{'color':'black','price':'1000'}}
]
이렇게 바꿔도 문제는 여전히 존재합니다. 바로, 딕셔너리는 키 중첩 문제가 있습니다. 그래서 가장 좋은 방법은 무엇일까요? 앞에서도 언급했던 것처럼 클래스 구조로 작성하는 것입니다.
class Cellphone(object):
def __init__(self, company, details):
self._company = company
self._details = details
def __str__(self):
return f'{self._company} - {self._details}'
phone1 = Cellphone('Apple',{'color':'white','price':'1000'})
phone2 = Cellphone('samsung',{'color':'black','price':'1000'})
print(phone1) # Apple - {'color': 'white', 'price': '1000'}
print(phone2) # samsung - {'color': 'black', 'price': '1000'}
지금은 인스턴스를 2개로 밖에 없지만, 실제 현업에서 사용되는 데이터는 무수히 많기 때문에, 이것들을 관리할 수 있는 객체 지향으로 짜는 것이 좋습니다. 이렇게 클래스를 한번 만들어 놓으면, 코드를 계속 반복할 필요가 없고, 코드 중복을 방지할 수 있으며 유지 보수하기도 편한 장점이 있습니다. 객체 지향이 더 좋지만 때로는 절차 지향으로 짜는 것이 편할 때도 있습니다. 작은 프로젝트처럼 크롤러를 만들거나 유틸성 프로그램을 만들 때에는 절차 지향 프로그래밍이 용이하기도 합니다.
결론
-
객체는 속성과 행위를 가지는 구현할 대상이며, 파이썬에서는 클래스를 활용해서 구현 가능할 수 있습니다.
-
객체 지향 프로그래밍은 장점(코드의 재사용, 코드 중복 방지, 유지보수 용이)이 많다!
-
다음 편에서는 객체 지향 언어의 특징인 캡슐화(encapsulation), 상속(inheritance), 다형성(polymorphism), 합성(composition)에 대한 내용을 작성하겠습니다.