파이썬 접근제한자 질문있습니다.

조회수 315회
class PayGildong:

    def __init__(self):
        self.day = 25
        self.__pay = 1000000

    def setPay(self, pay):
        self.__pay = pay

    def getPay(self):
        return self.__pay


gd = PayGildong()

gd.day = 14
gd.__pay = 800000

print(gd.__pay, gd.day)

이렇게 했을 때 gd.__pay = 800000 에서 오류가 나야 하는 걸로 보이는데 왜 오류가 안 나고 출력이 되는지 궁금합니다.

2 답변

  • 아래 문서를 참고하시면 도움이 될 것 같습니다.
    https://docs.python.org/ko/3/tutorial/classes.html?#private-variables

    객체 내부에서만 액세스할 수 있는 “비공개” 인스턴스 변수는 파이썬에 존재하지 않습니다. 하지만, 대부분의 파이썬 코드에서 따르고 있는 규약이 있습니다: 밑줄로 시작하는 이름은 (예를 들어, _spam) API의 공개적이지 않은 부분으로 취급되어야 한다는 것입니다.

  • 다음 코드에서 self.__pay_PayGildong__pay와 같이 설정됩니다. 이는 다음 코드에서 알 수 있습니다.

    class PayGildong:
        def __init__(self):
            self.day = 25
            self.__pay = 1000000
        # 생략
    
    gd = PayGildong()
    print(dir(gd))  # [... '_PayGildong__pay', ...]
    print(gd._PayGildong__pay)  # 1000000
    

    그렇기 때문에 언더바 2개를 넣더라도 표면적으로 보이지 않을 뿐, 어떤 방식으로든 접근할 수 있는 상태로 저장됩니다. (즉, 비공개 속성은 없습니다.)


    또한 gd.__pay = 800000 과 같은 코드는 _PayGildong__pay가 아닌, __pay라는 속성을 하나 만들게 됩니다. 이는 다음 코드를 통해 알 수 있습니다.

    class PayGildong:
        def __init__(self):
            self.day = 25
            self.__pay = 1000000
        # 생략
    
    gd = PayGildong()
    gd.__pay = 800000
    print(dir(gd))  # [... '_PayGildong__pay', '__pay', ...]
    print(gd._PayGildong__pay)  # 1000000
    print(gd.__pay)  # 800000
    

    마지막으로, @property를 통해 접근하는 것이 파이썬스러운(pythonic) 방법이라고 생각합니다. 다음 코드는 @property를 사용한 코드입니다.

    class PayGildong:
        def __init__(self):
            self.day = 25
            self._pay = 1000000
    
        @property
        def pay(self):
            return self._pay
    
        @pay.setter
        def pay(self, value):
            # if not isinstance(value, int):  # value가 정수가 아닐 경우
            #     raise TypeError  # 타입 에러 발생
            self._pay = value
    
    
    gd = PayGildong()
    
    
    gd.day = 14
    gd.pay = 800000
    # gd.pay = 800000.1  # TypeError
    
    
    print(gd.pay, gd.day)
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)