[Python] 정보은닉과 dict
속성 감추기
객체 외부에서 객체 내에 있는 변수, 속성에 직접 접근하지 못하도록 만들 수 있다.
class Person:
def __init__(self, n, a):
self.__name = n # 이름 정보
self.__age = a # 나이 정보
def add_age(self, a):
if(a < 0):
print('나이 정보 오류')
else:
self.__age += a
def __str__(self):
return '{0}: {1}'.format(self.__name, self.__age)
def main():
p = Person('James', 22) # 22살의 James
# p.__age += 1 # 이 문장을 실행하면 오류가 발생함
p.add_age(1)
print(p)
main()
변수를 언더바 두개를 속성이름 앞에 적어주면 외부에서 접근이 불가능하다.
class Person:
def __init__(self, n, a):
self._name = n # 이름 정보
self._age = a # 나이 정보
def add_age(self, a):
if(a < 0):
print('나이 정보 오류')
else:
self._age += a
def __str__(self):
return '{0}: {1}'.format(self._name, self._age)
def main():
p = Person('James', 22) # 22살의 James
# p._age += 1 # 이렇게 안쓰기로 약속했다.
p.add_age(1)
print(p)
main()
객체 내 변수 이름 앞에 언더바를 하나만 붙이면 이 변수에 직접 접근하지 없다고 약속하는 것이다. 위 코드와 같이 언더바를 하나 추가해서 변수의 이름을 결정하는 방법이 조금 더 보편적으로 사용된다.
__dict__
객체 내에 해당 객체의 변수 정보를 담고 있는 딕셔너리가 존재한다.
class Person:
def __init__(self, n, a):
self._name = n # 이름 정보
self._age = a # 나이 정보
def main():
p = Person('James', 22) # 22살의 James
print(p.__dict__)
main()
{'_name':'James', '_age':22}
객체 내에 __dict__가 있으며 이는 딕셔너리이다. 여기에는 해당 객체의 변수 정보가 담긴다.
class Person:
def __init__(self, n, a):
self._name = n # 이름 정보
self._age = a # 나이 정보
def main():
p = Person('James', 22) # 22살의 James
print(p.__dict__)
p.len = 178
p.adr = 'Korea'
print(p.__dict__)
main()
{'_name':'James', '_age':22}
{'_name':'James', '_age':22, 'len':178, 'adr':'Korea'}
위 코드와 같이 객체에 변수가 추가되면 또는 변수의 값이 변경되면 __dict__에도 그 정보가 반영된다.
class Simple:
def __init__(self, n, s):
self._n = n # 단순 정수
self._s = s # 단순 문자열
def __str__(self):
return '{0}: {1}'.format(self._n, self._s)
def main():
sp = Simple(10, 'my')
print(sp)
sp.__dict__['_n'] += 10
sp.__dict__['_s'] = 'your'
print(sp)
main()
10: my
20: your
__dict__의 정보를 수정함으로써 객체 내 변수의 값을 수정할 수도 있다. 이것을 통해 객체 내에 있는 변수의 값은 __dict__을 통해 관리할 수 있다는 것을 알 수 있다.
class Person:
def __init__(self, n, a):
self.__name = n # 이름 정보
self.__age = a # 나이 정보
def main():
p = Person('James', 22) # 22살의 James
print(p.__dict__)
main()
{'_Person_name': 'James', '_Person_age':22}
위 코드를 통해 __dict__에 등록된 속성의 이름이 다음과 같은 패턴으로 수정됨을 알 수 있다.
패턴 : __AttrName –> _ClassName__AttrName
즉 변수 이름에 언더바를 두 개 붙이면 파이썬은 위의 패턴대로 이름을 바꾼다. 물론 객체 내에서는 바뀌기 이전의 이름으로 접근이 가능하다. 그래서 객체 외부에서 접근이 불가능했던 것이다. 따라서 변수 이름에 언더바를 두개 붙이더라도 바뀐이름으로 접근한다면 그 접근까지 막지 못한다.