데이터 과학 유망주이 매일 글쓰기 — 스무 번째 토요일
추상화(Abstraction)
# 추상화, #ABC, #abstractmethod
오늘 한일:
오늘은 이번 주 배웠던 개념 중 가장 모호하다고 할 수 있는 추상화 개념에 대해 다루어보고자한다. 추상화라고 하니 피에트 몬드리안의 “추상화"가 생각났다. 잠깐 미술사를 다루어 보자면 사실주의가 유행이던 시절, 19세기 초 카메라가 나타나면서 인간이 아무리 사실적으로 물체를 그려도 사진을 따라갈 수 없게되자, 사물을 똑같이 따라 그리는 것이 크게 의미가 없어졌다고 한다. 그래서 화가들이 스스로 경쟁력을 갖기 위해 현실에 똑같이 존재하지 않는, 자신만의 세계관을 나타내는 다소 상징적인 그림들을 그리기 시작했다고 한다.
그렇다면 프로그래밍 세계에서는 추상화가 어떠한 개념으로 사용될까?
추상화(Abstraction)
추상화는 메소드의 실제적인 구현을 가리는 역할을 한다. 일단 추상화를 이해하기 위해 파이썬에서 제공하는 가장 기본적인 추상화용 모듈과 메소드에 대해 알 필요가 있다.
- ABC: 파이썬에 내장된 abc 라는 모듈의 클래스이다. ABC를 통해 클래스를 확장하거나 추상화 메소드를 포함시키면, 이 클래스로 부터 상속한 자녀 클래스는 자동적으로 그러한 추상화 메소드를 적용하게 된다.
- abstractionmethod: abc 모듈의 메소드로써, 메소드를 추상화된 메소드로 만들기 위해 사용한다. 만약 부모 클래스가 abstractmethod를 가졌으나 자녀 클래스는 추상화 클래스에서 상속하지 않을 경우, abstractmethod는 자동적으로 적용되지 않는다.
위 메소드를 활용한 예제를 통해 추상화가 어떻게 적용되는지 알아보자.
# 파이썬 내장 추상화 클래스 ABC와 abstractmethod 추상화 메소드 불러오기from abc import abstractmethod, ABC# 추상화된 부모 클래스 정의class Vehicle(ABC): def __init__(self, speed, year): self.speed = speed self.year = year def start(self): print(“Starting engine”) def stop(self): print(“Stopping engine”) @abstractmethod def drive(self): pass# 추상화된 부모 클래스로부터 상속한 자녀 클래스 정의class Car(Vehicle): def __init__(self, canClimbMountains, speed, year): Vehicle.__init__(self, speed, year) self.canClimbMountains = canClimbMountains def drive(self): print(“Car is in drive mode”)# 필요한 인자를 입력하여 클래스 객체화car = Car("Only for road", 30, 1997)# drive()메소드 실행car.drive()>> Car is in drive mode
여기서 ABC를 통해 추상화된 부모 클래스 Vehicle와, 이를 상속한 자녀 클래스 Car를 정의했다. 부모 클래스 Vehicle은 drive라는 abstractmethod 추상화 메소드를 통해 추상화된 메소드를 가지고 있다. Car는 부모 클래스가 이 추상화된 메소드를 가지고 있으므로, 역시 drive 메소드를 가져야 한다.(그렇지 않으면 에러가 난다.) 하지만, 추상화된 메소드의 목적이 실제 기능이 무엇인지를 보여주지 않는 것이기 때문에, 부모 클래스의 추상화된 메소드는 실행 내용이 없다. 부모 클래스에서 추상화된 메소드는 반드시 자녀 클래스도 가져야 하지만, 어떻게 보면 자녀 클래스는 추상화된 해당 메소드를 자신의 필요에 맞게 재정의가 가능하다고 볼 수도 있다.
이러한 추상화 기법을 활용하는 이유는, 일단 생각해 놓은 기능을 완전히 구현하기로 결정하지 않은 상태에서 시범적으로 자식 클래스를 만들어 구현해 놓을 수 있기 때문이다. 그렇게 하면, 부모 클래스를 다시 고치지 않아도, 자녀 클래스에서 해당 기능을 구현해보고, 나중에 부모 클래스에도 완전히 구현할지 하지 않을지를 결정할 수 있다. 즉, 아직 구현이 결정나지 않은 기능을 일단 시범적으로 테스트해 볼 수 있게 해 주는 것이다
또한 프로그램을 만들면서, 부모 클래스의 본래 기능을 고치지 않고, 자녀 클래스에서 독립적으로 특정한 메소드를 변경하고 싶을 경우 사용할 수 있다. 예를 들어서 특정한 케이스의 예외 처리를 위해, 일부러 부모 클래스의 추상화된 메소드를 만들어서, 이를 상속한 자녀 클래스에서 추상화된 메소드를 필요에 따라 조정할 수 있다. 협업 및 프로젝트 진행시 코드를 모니터링하고, 효율적인 개발을 위해 코드를 중간 중간 보완 및 수정하는데 도움이 되는 기법이라고 할 수 있다.
앞으로 할일:
이렇게 최대한 추상화의 방법과 목적에 대해 설명해보았지만, 아직도 이 개념이 추상적으로 느껴진다. 내가 이해하는 선에서는 어쨌던 아무 기능을 갖지 않은 함수가 부모 클래스에 존재하고, 그것을 자녀 클래스가 이어받아, 각 자녀 클래스의 같은 이름을 가진 함수들이 서로 다른 기능을 필요에 따라 구현할 수 있게 하는 방법이다. 그렇게 해서 부모 클래스의 해당 함수를 접근하려하는 사람들은 해당 함수가 텅빈 함수라는 것을 알게되고, 그것은 자녀 클래스에서 개별적으로 필요에 맞게 사용되는 추상화 함수라는 것을 알게된다. 결국 부모 클래스를 접근할 때는 그 함수가 각각의 자녀 클래스에서 어떻게 구현되었는지 알 수 없으므로, 그 기능이 어떻게 각 자녀 클래스에서 사용되는지에 대한 정보는 가려진다고 볼 수 있다.
오늘 다룬 추상화와 이전에 리뷰한 캡슐화관련 개념이 아직도 모호하다. 앞으로도 계속 써보면서 복습을 하고 공부해 보아야할 것이라고 생각한다. 어제 선생님께서 이러한 개념들이 아마도 코딩 인터뷰에서 많이 나올 것이라고 말씀을 하셨는데, 확실하게 이해가 되지 않더라도 논리적으로 자신이 이해한 바를 설명할 수 있어야 한다고 말씀하셨다. 이러한 개념을 완벽히 이해하기를 기대하지는 않을 수 있지만, 자신의 철학대로 풀어낼 수 있어야 한다는 것이다. 물론, 리스트, 딕셔너리, 튜플 등등이 어떻게 다른지는 바로 바로 5초 안에 대답할 수 있을 정도가 되어야 한다고 하셨다.
가면 갈수록 기초가 매우 중요하다는 생각이 다시든다. 복잡한 것을 알지는 못해도, 가장 기본적인 것은 바로 바로 적용할 수 있어야 하기 때문에, 어쩌면 그런 것들을 면접에서 가장 중요하게 보려는 것인지도 모른다. 그래서 지금 내게 주어진 이 시간을 최대한 활용하여, 프로그래밍에 대한 기본기를 잘 다져야겠다는 생각이 다시든다. 다시 한번 이러한 기본기를 탄탄히 다질 수 있게 도와주시는 선생님들과, 인터넷에 매우 유용한 자료를 올려주신 많은 블로거들에게 감사하다. 그리고, 나와 함께 이 배움의 여정을 최선을 다해 헤쳐나가는 동료 예비 데이터 사이언티스트들에게도 감사하다는 말을 하고싶다. 다 같이 화이팅!
참조: