클래스란 무엇인가?? 라는 개념 설명에 대한 포스트는 자바에서 한 적이 있다. 클래스 개념이해에 대한 부분은 참고한다.
https://digiconfactory.tistory.com/39
클래스에 대한 복잡한 기능을 구현하는 언어는 자바이다. 자바의 클래스를 만들려면 시작부터가 어려운 반면,
파이썬의 클래스는 그보다 단순하다. 사람에 대한 클래스를 정의해본다.
class Person:
pass
이것 만으로 만들었다.
mike = Person()
jane = Person()
이 코드는 클래스의 인스턴스를 만드는 코드이다. 매우 간단하다. mike 와 jane은 Person 클래스의 인스턴스이다.
클래스 챕터의 설명을 위의 포스트로 대체했으니 여기서 한 가지 개념설명을 짚고 넘어간다.
그림에서 보는 것과 같이 현실의 객체인 Person 의 컴퓨터상의 설계도가 Person 클래스이다. 설계도만 있지 실제 제품을 만들지는 않았다. 이 설계도를 가지고 만든 mike와 jane을 Person 의 인스턴스라고 한다. 한편 mike나 jane이나 둘다 자기의 독립된 메모리에 생성되었으므로 엄연히 객체이다. mike와 jane은 객체라고 한다. 프로그램 안에 실행되고 있는 개객체는 현실의 객체와는 다르다.
이 관계를 보면 주로 인스턴스라는 표현을 사용하는 이유를 알 수 있다. insinstantiate 라는 동사는 인스턴스를 만들다. 인스턴스화 한다는 것이다. 설계도를 가지고 제품을 만든다는 것이다. 인스턴스를 만들어야 클래스의 기능을 사용할 수 있다. 클래스는 인스턴스화 하기 위해 있다.
class Person:
def sayhello(self, name):
print("Hello Dear",name)
mike = Person()
jane = Person()
mike.sayhello("Mike")
jane.sayhello("Jane")
이 코드는 클래스의 메소드를 사용하는 것이다.
사실 파이썬의 클래스가 더 쉬워보이지만 설명이 부족하기 때문에 이해하기 훨씬 어렵다. 자바처럼 접근제어자와 참조형 같은게 없으니까 어디서 무엇부터 꺼내야 할지 모르게 된다.
이런 경우에는 그림이 도움이 된다.
함수에 self와 name 두개를 전달해야 하는데, "Mike" 문자열만 전달했다. 어떻게 되는건가? 여기서 self는 파이썬 메소드 정의시 명시적으로 사용해야 하는 매개변수이다. self는 바로 인스턴스인 mike 자신이다. 자신을 주는 것이니까 생략하는 것이다. 자바에도 비슷하게 this가 있는데 자바의 메소드는 파이썬처럼 self를 매개변수로 선언하지는 않는다. self가 무엇인지 생성자를 만들면서 알아본다.
컴퓨터를 하다보면 생성자라는 단어가 나온다. 가끔 보면 정확히 한글에 대응되는 단어인지 의심이 되는 단어들이 있다. 생성자 생소한 단어다. 들어본 적이 있는가?
영어로 Constructor 이다. construct, construction 단어를 들어본적이 있을 것이다. 고등학교 영단어이다. 그렇다 주로 빌딩이나 건축물을 만들 때 쓰는 단어다. 건설하다란 의미가 있다.
생성자라는 말이 이해가 안되는 것은 당연하다. 영어권 사용자들은 빌딩과 구조물을 건설하는 개념인데 한글은 생성이라는 동떨어진 단어를 사용하고 있다. 이 번역이 혹시 일본에서 잘못 전해진 것 아닌가?하는 의심이 들어 일본 웹을 찾아봤다. 일본도 콘스트라쿠타라는 Constructor의 외래어를 사용하고 있었다. 이것은 한국에 자바를 들여오는 과정에서 번역 실수가 의심이 되는 부분이다. 처음에 번역을 잘 못했더라도 시간이 지나 업계 용어로 정착이 되면 바꾸는 것이 힘들어 진다.
이렇게 문장을 만들면 원문과의 차이가 느껴진다.
Constructor를 건설자라고 하면
Person 클래스의 설계도를 가지고 mike라는 이름의 빌딩을 메모리에 건설했다. (빌딩은 인스턴스이다)
jane의 빌딩도 메모리에 추가로 건설할 것이다.
가 원어민이 받는 언어의 느낌이다.
Constructor를 생성자라고 하면(기존방식)
Person 클래스의 설계도를 가지고 mike라는 이름의 빌딩을 메모리에 생성했다. (빌딩은 인스턴스이다)
jane의 빌딩도 메모리에 추가로 생성할 것이다.
어떤가 어느 문장이 더 와닿는가? 생성이라는 동사에 어울리지는 않는 것 같다.
네이버 사전에서 생성의 뜻은
사물이 생겨남. 또는 사물이 생겨 이루어지게 함.
물론 쓸 수는 있다. 그런데 많이 추상적이다. 사물을 생기게 하는 것은 조물주와 자연의 영역이지 인간이 할일인지 잘 모르겠다.
인스턴스 빌딩을 건설하는 것과,
인스턴스 빌딩을 생성하는 것은 거리감이 좀 멀다.
번역이 완전히 틀린 것은 아닌데 구체적인 심상을 주지 못하는 단어라서 아쉽다. 더 세분화된 단어가 없었는가 싶다.
일본의 경우에는 외래어 표기가 있으니까 그렇게 사용했다. 우리나라는 외국의 문물은 좋아하면서 의외로 외래어 표기에 거부감이 있는 나라라서 그렇게 한건지... 법학책처럼 번역이 되어 있다.
그래서 글쓴이의 추천은 항상 같다. 원문을 사용하라는 것이다. 프로그래밍을 하기 위한 문서는 영어로 되어 있다. 어차피 온라인에서 stackoverflow를 읽던 pdf를 읽던 tutorial을 읽던 영어로 읽어야 한다. 영어로 읽는 것을 습관화하고 발음도 영어처럼 읽고 들어야 한다. 그래야 udemy에서 영어강의도 들을 수 있다.
Constructor 가 뭔지는 이야기 했으니 만들어볼 차례다.
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def getname(self):
return self.name
def getage(self):
return self.age
def setname(self,name):
self.name = name
def setage(self,age):
self.age = age
p1 = Person("강강술",31)
p2 = Person("해돋님",20)
print(p1.getname(), p1.getage())
print(p2.getname(), p2.getage())
p1.setname("황길치")
p1.setage(45)
p2.setname("장세라")
p2.setage(35)
print("="*8)
print(p1.getname(), p1.getage())
print(p2.getname(), p2.getage())
생성자는 클래스의 인스턴스가 만들어질 때 자동으로 생성된다. 자동 생성되는 생성자는
def __init__(self): pass
의 형태로 비어있다. 생성자에서 초기화가 일어난다. 파이썬 생성자의 이름을 __init__ 로 작명한 것은 개발자의 의도로 보인다. 이 사람(귀도 반 로썸)은 생성자가 초기화를 위한 공간이라고 생각한 것 같다. 파이썬의 생성자 __init__ 이란 이름을 기억한다.
생성자에 초기화를 시켜주려면 메소드를 오버라이드 하면 된다.
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
self 는 아까 이야기했듯이 인스턴스 자신의 참조를 말한다. 그래서 self.name 이란 인스턴스의 변수가 된다. 매개변수의 name과는 다르다. 그래서 self로 구분이 되어 있다. 이 값은 한번 설정하면 인스턴스가 메모리에서 해제될 때까지 사용되고 바뀔 수 있다. age도 마찬가지다.
def getname(self):
return self.name
def getage(self):
return self.age
def setname(self,name):
self.name = name
def setage(self,age):
self.age = age
OOP 스타일로 getter와 setter 메소드를 작성했다. 필요한 변수의 입출력을 한다.
p1 = Person("강강술",31)
p2 = Person("해돋님",20)
print(p1.getname(), p1.getage())
print(p2.getname(), p2.getage())
#출력값
강강술 31
해돋님 20
* 이제 인스턴스를 생성한다. 생성자에 들어가야할 인자를 전달한다. self는 위의 설명처럼 p1,p2가 들어가는 것이다.
클래스에 저장된 값을 꺼내서 사용한다.
값을 바꾸는 것은 setter 메소드로 한다.
p1.setname("황길치")
p1.setage(45)
p2.setname("장세라")
p2.setage(35)
print("="*8)
print(p1.getname(), p1.getage())
print(p2.getname(), p2.getage())
#출력값
========
황길치 45
장세라 35
여기까지 생성자를 작성해 봤다. 클래스는 단시간에 이해하기 힘들고 이해했다 하더라도 응용하는데 시간이 걸린다. 애초에 아키텍쳐를 그렇게 설계를 해놨다.
하지만 클래스를 제대로 이해하는 것이야 말로 소프트웨어 공학자가 되는 길이라 생각한다. OOP 객체지향 프로그래밍이라 하는데 4차 산업시대에 매우 필요한 학문이다.
객체지향프로그래밍을 통해 일반 대중들과 컴퓨터를 가지고 인문학적으로 소통할 수 있다. 그 외 컴퓨터 관련 주제들은 아직 대중이 관심을 가지기에는 좀 멀다. 커피숍에서 이진법과 32비트에 대하여 사람들과 대화하는 것 보다, 인공지능이 가지는 객체성에 대한 내용이 더 흥미를 끌게 된다. TV는 소통이고 상업성이니까 보여지는 모습이 중요하다고 생각한다.
클래스에 대한 내용은 워낙 어려운 개념이라 이 포스트에서는 개인적인 의견을 많이 반영했다. 기술에 대한 언급은 가급적 의견을 배제하고 딱딱한 내용을 유지하려고 노력해야하는데 이 블로그의 목적은 그것은 아니다. 어차피 누군가 나보다 먼저 알고 있는 사람들 즉 선배와 선생들의 가르침을 발전시키기 위해서는 꾸준한 연구와 의견이 필요하다고 본다.
그래서 영문자료를 찾고 이웃나라 일본의 자료도 찾아보는 이유가 틀을 깨기 위해서이다. 또 글쓴이의 의견이 틀릴 수도 있다. 인터넷에 문서는 수십억개가 넘지만 그 것들이 정확히 맞는지는 각자의 입장에서 판단하면 된다. 그래서 구글의 검색엔진이 있는 것이다. 수백만개에 달하는 문서를 정확도 순으로 정리해주는 것이고 우리는 구글의 검색결과에 대하여 어느정도 신뢰를 가지고 사용하는 것이다.
*이 블로그에서 사견이 많이 들어간 포스트는 추후 업데이트 시 변경될 가능성이 상당히 높다.