나의 공부 일기

Python) 정보은닉(Information Hiding) 본문

파이썬/파이썬 정리

Python) 정보은닉(Information Hiding)

곽병권 2023. 10. 20. 12:58
728x90

파이썬에서는 정보 은닉(외부 접근 제한)을 표현하는 방법입니다.

파이썬에서는 접근 지정자의 지원이 타 OOP언어에 비해 느슨합니다.

 

'_'(underscore)문자를 이용하여 비슷한 개념을 표현합니다.(name mangling)

_ : 외부 접근을 제한한다는 개념 (타 OOP 언어에서 protected개념과 비슷합니다. 강제성은 없습니다.)

__: 해당 형식에서만 접근 가능함 (타 OOP 언어에서 private개념과 비슷합니다. 강제성은 없습니다.)     

 

 

속성과 메서드 모두 적용 가능합니다.

멤버 접근 제한이나 하위 클래스의 오버라이딩을 제한하는 용도로 사용됩니다.

__ 의 기본적 형태는

class exam:
    def __init__(self, name=None, age=0):
        self.__name = name
        self.__age = age

    def printInfo(self):
        print(self.__name, self.__age)

이런식으로 변수 self뒤에 __ 를 붙여주며 사용합니다.

 

 

 

 

제한이 있을때와 _ 일때  __ 일때를 나눠 뭐가 어떻게 다른지 정리해보겠습니다.

 

 

먼저 제한이 없을때 입니다.

class exam:
    def __init__(self, name=None, age=0):
        self.name = name
        self.age = age

    def printInfo(self):
        print(self.name, self.age)


def main():
    p1 = exam('홍길동', 20)
    print(p1.__dict__)
    print(dir(p1))
    p1.__dict__['age'] = 30
    print(p1.age)
    p1.printInfo()
    print(p1.age)
    print(dir(p1))
 
main()

dir은 () 안의 객체에 어떤 메서드 어떤 변수를 가지고있는지 모두 표시해주는 파이썬의 내장함수 입니다.

 

제한이 없을때 사용한다면

{'name': '홍길동', 'age': 20}
 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'age','name', 'printInfo']
30
홍길동 30
30
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'age','name', 'printInfo']

이렇게 변화가 없는것을 볼 수 있습니다.

 

 

_를 사용했을때의 코드입니다.

class exam:
    def __init__(self, name=None, age=0):
        self._name = name
        self._age = age

    def printInfo(self):
        print(self._name, self._age)


def main():
    p1 = exam('홍길동', 20)
    print(p1.__dict__)
    print(dir(p1))
    p1.__dict__['age'] = 30
    p1.__dict__['_age'] = 40
    print(p1.age)
    p1.printInfo()
    print(p1.age)
    print(dir(p1))

 

_을 사용했을때의 결과값입니다.

{'_name': '홍길동', '_age': 20}
 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__','_age', '_name', 'printInfo']
30
홍길동 40
30
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', '_name', 'age', 'printInfo']

처음 dir을 사용했을땐 위에 제한이 없을때와 같지만 _age가 있지만 _age가 아닌 age에 값을 집어넣게 되면

이렇게 dir에 age가 하나 추가된것을 볼 수 있습니다.

 

 

__를 사용했을때의 코드 입니다.

아 우리는 __ 이것을 던더(double underscore)라고 주로 부릅니다.

class exam:
    def __init__(self, name=None, age=0):
        self.__name = name
        self.__age = age

    def printInfo(self):
        print(self.__name, self.__age)


def main():
    p1 = exam('홍길동', 20)
    print(p1.__dict__)
    print(dir(p1))
    p1.__dict__['age'] = 30
    p1.__dict__['__age'] = 40
    print(p1.age)
    p1.printInfo()
    print(p1.age)
    print(dir(p1))


main()

_를 사용했을때랑 _ 하나의 차이밖에 없지만 결과값은 많이 다릅니다.

 

결과값입니다.

{'_exam__name': '홍길동', '_exam__age': 20}
 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_exam__age', '_exam__name', 'printInfo']
30
홍길동 20
30
['__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__','__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_exam__age', '_exam__name', 'age', 'printInfo']

사용하지도 않은 __exam 이 붙어있는걸 확인할 수 있습니다. 

 

뭐 강제로 p1.__idct__['_exam__age'] = 40 을 하여 값을 변경할 순 있지만 의미가 없는행동입니다.

 사용하지 말라고 파이썬에서 이렇게 설정해놓은것이기 때문이죠

 

 


여기까지 정보은닉에 대해 정리해보았습니다.

 

다음은 setter와 getter에 대해 정리해보겠습니다.

728x90

'파이썬 > 파이썬 정리' 카테고리의 다른 글

Python) Object 클래스  (0) 2023.10.24
Python) getter/setter  (0) 2023.10.23
Python) 함수 / 메서드  (0) 2023.10.19
Python) Class(클래스)  (1) 2023.10.18
Python) 객체지향프로그래밍 OOP(Class)란?  (0) 2023.10.18