파이썬의 클래스에 대한 포스팅을 한 적이 있다. 이 내용은 그때 다루지 못한 부분들을 보완하기 위한 포스팅이다.
비슷한 내용이겠지만 좀 더 세밀한 내용으로 보완하려고 한다.
파이썬은 객체지향언어이다. 모듈과 함수를 많이 써서 그렇게 느끼지 않았을 수도 있는데 파이썬의 모든 것은 객체로 이루어져 있다.
a = 10
print(type(a))
가장 자주 쓰는 int 형 변수는 int 클래스이다.
a 변수는 int 클래스의 인스턴스이다 라는 문장이 성립한다.
int는 C언어에서는 그저 4바이트에 42억개 범위에서 표현가능한 숫자형 자료이다. 파이썬에서는 속성과 메소드를 가진 클래스니까 근본적으로 다르다.
객체지향 프로그래밍 언어의 대명사인 자바와는 문법적 차이가 있다.
자바나 C++에 이미 익숙한 사람이라면 적응에 시간이 걸릴 수 있을 것이다. 그러나 결국 같은 개념을 다른 방식으로 표현한 부분들이기 때문에 한번이라도 OOP를 배운 사람이라면 적응에 오래걸리지 않을 것이다.
우선 클래스부터 만들어보자.
class Machine:
pass
myRobo = Machine()
print(type(myRobo))
for i,v in dict(locals()).items():
print(i,":",v)
가장 간단한 클래스 형태는
class 클래스명:
pass
이다.
클래스의 인스턴스를 생성하는 은
변수 = 클래스() 이다. 이 때 클래스의 인스턴스를 생성한다.
결과창을 보면 __main__ 의 Machine 클래스이다. 어디 소속된 클래스인지 알 수 있다.
다음은 메서드이다.
class Machine:
def square(self,a):
return a*a
myRobo = Machine()
print(myRobo.square(10))
*결과값 : 100
제곱하는 메서드를 만들었다. 메서드의 첫번째 매갠변수는 항상 self 여야 한다.
self는 자바의 this 같은 개념인데 파이썬에서는 명시적으로 써준다. 여기서 self 는 myRobo라는 인스턴스 변수라고 생각하면 된다.
메서드는 함수처럼 def 키워드로 작성한다. 들여쓰기 규칙(indentation)은 항상 지켜줘야 한다. 들여쓰기가 파이썬의 가장 큰 어려움중 하나일 것이다. 공백 4칸을 머리속에 넣고 IDE를 잘 활용하면 대부분 자동으로 들여쓰기가 된다.
메서드를 봤으니 속성을 만들어 본다. 속성은 객체지향 프로그래밍에서 인스턴스 변수, 멤버 변수 등의 다양한 이름을 갖고 있다. 인스턴스를 생성한 후에 사용할 수 있는 독립적인 변수라고 생각하면 된다.
class Machine:
def __init__(self):
self.a = 0
self.b = 0
def set_variable(self,a,b):
self.a = a
self.b = b
def add(self):
return self.a + self.b
def sub(self):
return self.a - self.b
def mul(self):
return self.a * self.b
myRobo = Machine()
myRobo.set_variable(10,7)
print('Add:', myRobo.add())
print('Sub:', myRobo.sub())
print('Mul:',myRobo.mul())
속성 변수는 __init__ 에서 선언한다. 이 초기화 블록은 인스턴스가 만들어질 때 처음 한번 실행되는 코드이다.
self.변수이름 으로 작성하면 된다. 사실 다른 메소드에 속성을 계속 추가하능 것도 허용이 된다. 단 그 메소드를 실행시키기 전에는 생성되지 않는다. 왜 인스턴스를 생성할때 __init__을 불러와서 실행시키는지 알수 있다. 무조건 실행되기 때문에 여기에 인스턴스 변수를 초기화하는 것이다.
인스턴스 변수가 일단 생성되면 객체를 소멸시키기 전까지 상태가 유지된다. 파이썬 내부의 GC (가비지 콜렉터)가 관리를 하지만 용량이 큰 인스턴스를 만들 때는 소멸시기를 직접 컨트롤 하는게 좋다.
예제에서는 생성자에서 인스턴스 변수를 만들었고, set_variable 에서 값을 지정했다.
나머지 메소드들은 인스턴스안에 있는 값을 가져와서 덧셈,뺄셈,곱셈을 완료했다. 전역변수를 사용했을 때와 다르게 느껴질 것이다. 인스턴스는 하나의 독립성을 갖고 있다. 인스턴스 내부에서 일어나는 일들이 다른 코드에 영향을 주지 않기 때문에 관리가 용이하다. (전역변수와 비교해보자.)
예제의 코드는 모두 public 으로 외부에 공개되어 있다. 외부에서 사용하려면 myRobo.a 를 사용한다.
속성값을 변화시키는 방법은 여러가지 인데 위 코드 처럼 setter를 만들어서 사용하는 경우도 있고 보통은 초기화블록 __init__ 생성자에 매개변수를 넘겨준다.
def __init__(self,a,b):
self.a = a
self.b = b
여기서 매개변수 a와 self.a는 전혀 다른 변수임에 주의한다. a는 생성자의 인수로 받은 것이고 self.a는 멤버 변수이다.
다음 포스팅에서 속성의 접근제어 방법 등에 대하여 포스팅 예정이다.