클래스와 관련해서 작성된 2개의 글을 통해, 클래스의 멤버 변수와 메소드, 그리고 생성자 메소드에 관한 내용까지 알아보았다. 오늘은 한 걸음 더 나아가서, 클래스의 접근자에 관한 내용을 알아보자.
본론으로 들어가기 전에 위 그림을 잠깐 들여다보자. 그림의 예제 프로그램에서는 clsMember라는 클래스가 하나 정의되어 있고, person01이라는 객체도 하나 정의되어 있다. 그리고, iCount라는 클래스 멤버 변수가 하나 있고, dictProfile이라는 딕셔너리를 객체의 멤버 변수로 가지고 있다. clsMember 클래스는 setName과 getName이라는 메소드도 가지고 있다. 메소드의 내용을 보면, 이름을 전달 받아 딕셔너리의 원소로 추가하는 동작과 딕셔너리 안에서 이름을 반환하는 동작이 정의되어 있다. 하지만, 실제로는 메소드를 통해 접근하지 않고 객체를 통해 직접 딕셔너리에 원소를 추가하고 있다.
이렇게 클래스 외부에서 객체를 통해 접근할 수 있도록 정의된 멤버 변수와 메소드를 Public 멤버 변수 또는 메소드라고 부른다. '공공의' 라는 의미를 갖는 퍼블릭은 이름 그대로 언제 어디서나 접근할 수 있는 그런 멤버 변수이고 메소드이다.
만약, clsMember가 어떤 동호회나 가게의 회원 명부 관리 프로그램을 위해 만들어진 클래스이고, 객체의 생성을 통해 회원을 추가 관리한다고 가정해보자. 회원의 이름이나 성별, 연락처와 같은 정보들을 객체의 퍼블릭한 멤버 변수로 정의하고, 클래스의 외부에서 자유롭게 접근해서 데이터를 변경하는 방식도 물론 가능하다.
하지만, 객체의 속성과도 같은 멤버 변수를 너무 무분별하게 접근할 수 있도록 열어둔다면, 데이터가 변경되는 경로가 너무 다양해지므로 프로그램을 작성하는 과정에서 의도하지 않은 데이터 변경이 생기면서 원치 않는 결과를 얻게 될 수 있다. 이런 부분을 방지하기 위해 클래스에는 접근 제한자를 제공한다.
위 그림은 처음 예제 프로그램의 딕셔너리 멤버 변수를 Private 타입으로 변경한 프로그램이다. '개인의' 라는 의미답게 접근 제한자가 프라이빗으로 정의된 멤버 변수를 클래스 외부에서 접근하면 위 그림과 같이 에러 메시지가 출력된다.
하지만, 클래스 내부에서는 프라이빗 멤버 변수에 자유롭게 접근할 수 있다. 따라서, 클래스를 정의할 때 멤버 변수와 메소드에 퍼블릭 또는 프라이빗이라는 접근 제한자를 지정함으로써 클래스 외부에서 접근할 수 있는 범위를 선택적으로 정의할 수 있다.
다시 원점으로 돌아와서, 위 그림의 예제 프로그램에서는 회원 정보를 의미하는 딕셔너리 타입의 프라이빗한 멤버 변수가 정의되어 있다. 그리고, 클래스를 객체라는 요소로 실체화시키는 외부 프로그램에서 회원 정보를 입력하거나 확인하는 등의 작업이 요구될 것이다.
지금까지의 설명으로는 프라이빗한 멤버 변수를 정의하였으므로, 외부 프로그램에서 객체를 통해 직접 참조는 불가능하다. 하지만, 클래스 내부에서는 접근이 자유로우므로, 위 그림처럼 외부 프로그램에서 호출이 가능한 퍼블릭 메소드를 정의하고, 이런 메소드를 통해 값을 전달하거나 반환받아서 확인할 수 있다. 그리고 이런 메소드를 일명 get/set 메소드라고 부른다.
위 그림과 같은 get/set 메소드로도 충분히 프라이빗한 멤버 변수의 값을 변경하거나 참조하는 것이 가능하다. 하지만, 값을 변경하거나 참조할 때마다 매번 메소드를 호출하는 방식으로 사용하는 것보다 변수를 직접 불러오는 형태가 프로그램의 작성을 좀 더 수월하게 만들어 줄 수 있다.
이럴 때 Property가 적절한 해답이 될 수 있다. 위 그림에서는 클래스 내부에 name이라는 이름의 프로퍼티를 추가하였다. 그리고, get과 set 메소드를 프로퍼티 내부에 지정하였다. 그 결과 클래스의 외부에서 마지막으로 정의한 프로퍼티의 이름을 마치 변수처럼 활용할 수 있게 되었다.
하지만, 이것 또한 뭔가 맘에 들지 않는다. 결국 프로퍼티를 사용하기 위해서는 get과 set 메소드를 각각 정의하고 이들의 접근자를 따로 지정해야만 한다. 내가 원하는 그런 기능을 구현하기 위해 상당히 어수선한 느낌이 든다.
이런 나의 마음을 아는지, 파이썬에서는 데코레이터를 이용해서 프로퍼티를 지정할 수 있도록 기능을 제공하고 있다. 위 그림은 get/set 메소드를 프로퍼티로 지정하는 예를 보여주고 있는데, get 메소드 앞에는 @property를, set 메소드 앞에는 @메소드 이름.setter를 붙여주면 메소드를 정의함과 동시에 프로퍼티로도 사용할 수 있게 된다.
'Programming > Python' 카테고리의 다른 글
Python: Module (0) | 2021.01.28 |
---|---|
Python: Class04 (0) | 2021.01.27 |
Python: Class02 (0) | 2021.01.25 |
Python: Class01 (0) | 2021.01.24 |
Python: Try & Exception (0) | 2021.01.22 |