먼저

class를 활용해 사각형의

넓이를 구하는 코드를 작성해 보자.

 

 

 

사각형이라는 클래스가 있고

너비와 높이를 속성으로 갖게

해준다.

 

 

 

너비와 높이 값은 생성자로부터

전달을 받게 한다.

 

 

 

이제 self.너비에 너비를 넣고,

self.높이에 높이를 받는 형태로

너비와 높이를 지정해 준다.

 

 

 

이를 기반으로 사각형의 넓이를

구하는 함수를 하나 만들어 주고

자신의 너비와 높이를 곱해

return 해준다.

 

 

 

이제

원하는 너비와 높이의 값을 담은

사각형을 특정 이름의 변수에 담아

만들어주고

 

 

 

위에 만들어둔 넓이를 구하는 함수를

호출하게 되면 입력해둔 너비와 높이

값을 곱한 사각형이 출력된다.

 

 

 

 

class Rect:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def get_area(self):
        return self.width * self.height

rect = Rect(100, 100)
print(rect.get_area())

 

 

 

 

여기까지는 아주 기본적이고

무난한 코드라 이제 이 정도는

쉽게 작성할 줄 알아야 한다.

 

 

 

아무튼,

 

 

 

여기까지는 좋았는데 갑자기

사용자가 갑자기 돌발행동을

한다고 가정해보자.

 

 

 

 


 

 

 

 

상황 1.

 

 

 

 

일반적으로 넓이를 구할 때는

양수만을 사용하는데 사용자가

값으로 음수를 넣었다.

 

 

 

하지만 프로그램은 출력 오류 없이

정상 작동되었으며 다만 결괏값이

양수가 아닌 음수로 출력되었다.

 

 

 

하지만 이것은 개발자의

의도를 벗어난 상황이므로

이런 일이 발생할 것을 대비해

미리 방어책을 세워둘 수 있겠다.

 

 

 

방어책으로는

조건문과 raise 함수를 활용해

예외(exception)를 발생시켜

사용자가 음수를 지정하지 못하도록

하는 것!

 

 

 

class Rect:
   def __init__(self, width, height):
       if width <=0 or height <= 0:
          raise Exception ("음수가 올 수 없습니다")    
       self.width = width
       self.height = height

   def get_area(self):
       return self.width * self.height

rect = Rect(-25, 25)
print(rect.get_area())

   

성공!

 

 

 


 

 

 

 

상황 2.

 

 

 

 

하지만 사용자는 똑똑했고

음수를 변수로 지정해 주면 다시금

음수 사용이 가능하는 것을 알았다.

 

 

 

예)

rect.width = -25 or

rect.height = -25 등..

 

 

 

class Rect:
   def __init__(self, width, height):
       self.width = width
       self.height = height
       if width <=0 or height <= 0:
           raise Exception ("음수가 올 수 없습니다")
   def get_area(self):
       return self.width * self.height
rect = Rect(25,25)

rect.width = -25
rect.height = 15

print(rect.get_area())

 

 

 

 

이렇게 하면 다시

아무 문제없이 -375 즉,

음수가 출력되고 만다.

 

 

 

 

흠..

 

 

 

 


 

 

 

 

프라이빗 함수

 

 

 

 

바로 이러한 상황을 대비하여

어느 누가 내 class를 사용하더라도

개발자의 의도와 기본값을 바꿀 수

없도록 차단해 주는 방법이 있는데

 

 

 

바로

self.매개변수로 시작되는

속성을 사용할 때,

 

 

 

매개변수 이름 앞에

언더바 두 개를 붙여사용하게 되면

해당 속성은외부에서 조작할 수 없는

속성이 된다.

 

 

 

 

예) self.__width

 

 

 

 

프로그래밍 언어에 따라 방법이 다른데

파이썬의 경우는 앞쪽에 언더바 두 개.

 

 

 

class Rect:
   def __init__(self, width, height):
       if width <= 0 or height <= 0:
           raise Exception("음수가 올 수 없습니다")
       self.__width = width
       self.__height = height

   def get_area(self):
       return self.__width * self.__height

rect = Rect(25,25)
rect.__width = -25
print(rect.get_area())

호우!

 

 

 

 

한번 언더바 두 개의

키워드에 접근을 해

속성을 확인해 보자.

 

 

 

print(rect.__width)

 

 

 

 

 

 

 

 

 

해당 키워드는 아예 속성이 없다

라는 에러가 뜨는 것을 볼 수 있는데

 

 

 

여기서 알 수 있듯이

언더바 두개로 시작하는 속성은

외부에서 아예 접근을 할 수 없는

변수가 되어 버리는 것!

 

 

 

이와 같이 코드를 작성할 경우

처음 매개변수의 인자 값을

설정할 때만 값을 넣을 수 있고

 

 

 

이후로는 접근이 불가능하게 되어

너비와 높이가 언제나 양수일 것을

보장해 주게 된다.

 

 

 


 

 

 

 

 

하지만 이렇게 값을 변경할 수

없게 되자 개발자들은 불만을

갖게 되고

 

 

 

이런 불만을 해결하기 위해

게터 세터라는 방법이 나왔다.

 

 

 

getter / setter

 

 

먼저

get이라는 이름으로 시작되고

set이라는 이름으로 시작되는

함수를 게터와 세터라고 부른다.

 

 

 

게터의 경우

자기가 가지고 있는,

외부에 노출하지 않은 속성을

return 하는 방법으로 사용하며

 

 

def get_width(self):

return self.__width

 

 

세터의 경우

외부에서 접근할 수 없는 속성의

값을 지정하는 역할을 한다.

 

 

def set_width(self, width) :

self.__width = width

 

 

이렇게 해주면 기본적인

게터와 세터가 완성.

 

 

 

def get_width(self):

return self.__width

def set_width(self, width) :

self.__width = width

 

 

 

각 세터 부분에는 조건문 등을

활용해 조건을 달아줄 수 있으며

 

 

 

이제 이렇게 해줌으로써

너비와 높이를 보다 안전하게

사용할 수 있게 되었다.

 

 

 

 

lass Rect:
   def __init__(self, width, height):
       if width <= 0:
           raise Exception("음수가 올 수 없습니다")
       self.__width = width
       self.__height = height


#게터세터 + 세터에 조건문
   def get_width(self):
       return self.__width
   def set_width(self, width):
       if height <= 0:
           raise Exception("음수가 올 수 없습니다")
       self.__height = height


#게터세터 + 세터에 조건문
   def get_height(self):
       return self.__height
   def set_height(self, height):
       if width <= 0 or height <= 0:
           raise Exception("음수가 올 수 없습니다")
       self.__width = width


   def get_area(self):
       return self.__width * self.__height


rect = Rect(-25,25)
print(rect.__width)

rect.__width = -25
print(rect.get_area())

 

 

 

 


 

 

 

사용법

 

 

 

 

만약 너비 값을 10

증가시키고 싶은 경우

 

 

 

rect.get__width() + 10

을 set에 담아준다.

 

 

 

rect.set__width( rect.get__width() + 10 )

 

 

 

 

 

 

 

 

 

 

+10이 반영된 것을 볼 수 있다.

 

 

 

 

 

참고로

 

 

 

게터와 세터를 무조건 적으로

만들어야 하는 것은 아니며

 

 

 

둘 중 필요한 것만 넣어

사용하거나 원하지 않을 경우에는

아예 넣지 않는 경우도 있다.

 

 

 

 


 

 

 

 

 

하지만 또다시,

 

 

 

코드를 사용하는 측에서

불만이 터져 나오게 되어

한 번 더 코드가 진화하게 되는데

그것이 바로 프로퍼티이다.

 

 

 

 

 

프로퍼티 (property)

 

 

 

 

 

우리나라에서는 속성은

다 똑같이 속성이라고

표현하는데

 

 

 

영어에서는

기본적인 속성을

attribute이라 하고

 

 

 

어떤 처리를 해준 속성은

프로퍼티로 구분 짓는다.

 

 

 

프로퍼티를 사용할 때는

@property 표시를 사용하고자 하는

게터 함수 위에 선언해 주고

 

 

 

게터 키워드를 제거한

순수 키워드를 사용,

 

 

 

세터 위치 위에 @와 함께

게터 위치에서 사용한

순수 키워드.setter를

입력해 놓으면 세팅이 완료된다.

 

 

 

출력할 때는 해당 순수 키워드

+ 추가 값 형태로 호출해

사용하면 되는데

 

 

 

   @property
   def width(self):
       return self.__width
   @width.setter
   def width(self, width):
       if width <= 0:
           raise Exception("음수가 올 수 없습니다")
       self.__width = width

   def get_area(self):
       return self.__width * self.__height

rect = Rect(20,20)

#rect.set_width(rect.get_width() + 10)
rect.width += 10

print(rect.get_area())

 

 

 

 

게터 세터 보다 훨씬 간단한

형태로 원하는 값을 추가할 수 있다.

 

 

 

#rect.set_width(rect.get_width() + 10)

vs

rect.width += 10

 

 

 

 

 

참고로

 

 

 

 

프로퍼티 앞에 붙는 골뱅이 @

표시는 데코레이터 라고 부르는데

 

 

 

프로퍼티 사용 예에서 볼 수 있듯

특정 함수에 추가적으로 꾸며질

구문 등을 정의해서 손쉽게 재사용이

가능하도록 돕는 역할을 한다.

 

 

 

파이썬 개발을 할 때 대부분

사용하지 않는 기능이라고 하니

그냥 이런 게 있다는 것만 확인하고

넘어가자.

 

 

 

 

 

 

 

 

 

728x90
반응형

'프로그래밍 > Python' 카테고리의 다른 글

기초) 기본 표준 모듈 샘플  (0) 2020.06.09
기초) 모듈  (1) 2020.06.08
기초) 특수 함수  (0) 2020.06.07
기초) 클래스의 개념과 기본 선언  (0) 2020.06.05
기초) Class와 객체지향 프로그램  (0) 2020.06.04

+ Recent posts