본문 바로가기
멋쟁이사자처럼 AI스쿨

getter, setter, mangling(파이썬 강의 Day5)

by 헬푸밍 2023. 1. 6.

getter, setter

객체의 내부 변수에 접근할 때 특정 메서드를 거쳐서 접근할 수 있도록 하는 방법

 

일단... 비밀번호를 설정할 수 있는 코드를 작성해보자!

class Person:

    def __init__(self, pw):
        self.hidden_pw = pw
    
    @property
    def pw(self):
        print('getter')
        return self.hidden_pw   #함수를 거쳐서 데이터를 가져오고

    @pw.setter
    def pw(self, pw):
        print('setter')
        self.hidden_pw = pw    #함수를 거쳐서 데이터를 설정한다.

첫 번째 방법은 위와 같이 데코레이터를 사용하는 방법이다

 

객체를 생성해 비밀번호를 'abcd'로 생성해보자!

person = Person('abcd')

그 다음...

person.pw = 'qwer'

세터에서 비밀번호를 'qwer'로 설정해보자

이렇게 'setter'가 출력된 것을 보면 setter의 함수가 작동했다.

 

아래의 코드를 통해 게터로 확인을 해보면...

person.pw

게터를 통해 비번을 가져오는데 'qwer'인 것을 보면 setter에서 비번이 잘 바뀐 것을 알 수 있다!

 

코드를 좀 더 발전시켜서...

 

1. 게터를 통해 비번을 가져오면 앞 두자리만 보이게!

2. 세터를 통해 비번을 바꾸려면 원래 비밀번호를 입력하게!

3. 원래 비밀번호가 틀리면 'wrong passworld!'가 출력되게!

하면...

class Person:

    def __init__(self, pw):
        self.hidden_pw = pw
    
    @property
    def pw(self):
        print('getter')
        return self.hidden_pw[:2] + '****' # 비밀번호 앞두글자만 보여줌

    @pw.setter
    def pw(self, new_pw):
        print('setter')
        input_pw = input('insert password :')
        if input_pw == self.hidden_pw:
            self.hidden_pw = new_pw
        else:
            print('wrong password!')    # 비밀번호를 바꾸려면 원래 비밀번호 입력해야함.

이런 코드가 만들어진다.

 

person = Person('abcd')

객체를 생성할 때 비밀번호를 'abcd'로 하고

person.pw = 'qwer'

세터로 비밀번호를 'qwer'로 다시 설정하려하면...

이렇게 현재 비밀번호를 입력하는 창이 뜬다.

 

먼저 비밀번호를 틀리게 입력해보자

'wrong password!'가 출력된다.

 

이번에는 현재 비밀번호를 올바르게 'abcd'로 넣어보자!

이렇게 잘 넣어주고...

 

게터로 패스워드를 확인하면...

person.pw

아래와 같이 게터가 실행되고 비밀번호가 abcd로 바뀐 것을 확인할 수 있다!

게터와 세터를 사용하는

두번째 방법은...

class Person:

    def __init__(self, pw):
        self.hidden_pw = pw

    def getter(self):
        print('getter')
        return self.hidden_pw[:2] + '****' # 비밀번호 앞두글자만 보여줌

    def setter(self, new_pw):
        print('setter')
        input_pw = input('insert password :')
        if input_pw == self.hidden_pw:
                self.hidden_pw = new_pw
        else:
            print('wrong password!')

    pw = property(getter, setter)   #게터 세터를 이렇게 지정할 수도 있음 이 방법이 가독성이 더 좋음

이렇게 게터와 세터를 함수이름에 적은뒤...

맨밑에 property(getter, setter)를 변수 선언해주는 방법이다.

 

이 코드도 객체를 만들고 실행해보면 똑같은 결과를 얻을 수 있다!

개인적으로는 이코드가 게터와 세터를 알아보기 편한 것 같다!

 

그런데...

person.hidden_pw = 'qqqq'

이렇게 직접 비밀번호에 접근해서 설정하고 비밀번호를 확인해 보면...

person.pw

아래처럼 비밀번호가 바뀐다!

 

이런 현상을 방지하기 위해 magling을 사용한다.

magling

변수에 직접적으로 접근하는 것을 막는 방법

변수명 앞에 __를 붙여 사용

 

맹글링을 사용해 코드를 고쳐보면... 아래와 같다.

class Person:

    def __init__(self, pw):
        self.__hidden_pw = pw   #maingling

    def getter(self):
        print('getter')
        return self.hidden_pw[:2] + '****' # 비밀번호 앞두글자만 보여줌

    def setter(self, new_pw):
        print('setter')
        input_pw = input('insert password :')
        if input_pw == self.__hidden_pw:
                self.__hidden_pw = new_pw
        else:
            print('wrong password!')

    pw = property(getter, setter)

hidden_pw를 싹다 __hidden_pw로 바꿔줬다!

 

객체를 생성하면서 비밀번호를 설정하고...

person = Person('abcd')

직접 바꿔봐도

person.__hidden_pw = 'qqqq' # 직접 바꿔봐도

비밀번호가

person.pw   # 데이터 그대루인 것 을 확인하자

아래처럼 그대로 인 것을 확인할 수 있다.

 

왜 그런 것인가 dir()함수를 통해 클래스 Person의 메서드를 확인해 보면...

print(dir(person))

__hidden_pw가 아니라 __Person_hidden_pw 메서드가 존재하는 것을 확인할 수 있다.

 

그래서 __Person_hidden_pw를 통해 바로 바꾸고 비밀번호를 확인해보면...

person._Person__hidden_pw = 'aaaa'
person.pw

이렇게 비밀번호가 바뀌었다.

 

맹글링도 변수에 직접적으로 접근하는 것을 완벽히 막아주진 못한다는 것을 알 수 있다.


이번에는 게터, 세터, 맹글링을 알아봤네여...

 

완벽하게 이해하려면 더욱 많은 공부가 필요할 듯 합니다...

 

다음 시간에 봐요~

댓글