출처 : 윤성우의 열혈 파이썬 : 중급
28. 정보 은닉과 __dict __
속성 감추기
#person.py
class Person:
def __init__(self, n, a):
self.name = n
self.age = a
def __str__(self):
return '{0}: {1}'.format(self.name, self.age)
def main():
p = Person('James', 22)
print(p)
p.age -= 1 # 프로그래머의 실수
print(p)
main()
- 오류가 발생한 근본적 원인은 객체 외부에서 객체 내에 있는 변수(속성)에 직접 접근하도록 내버려 두었기 때문이다
메소드 사용
#person2.py
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)
p.add_age(2)
print(p)
main()
- 여전히 변수에 접근할 수 있다
#person3.py
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)
p.__age += 1 # 오류 발생
p.add_age(1)
print(p)
main()
- 변수 이름 앞에 언더바를 두 개 이어서 붙여주변 외부에서 접근하는 것이 불가
- 객체 내 변수(속성) 이름 앞에 언더바를 하나만 붙이면 이 변수에 직접 접근하지 않겠다는 약속
- 더욱 보편적으로 사용된다
#person4.py
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)
p._age += 1 # 오류 발생은 하지 않으나, 이렇게 안쓰기로 약속했다
p.add_age(1)
print(p)
main()
__dict __
# person_dict2.py
class Person:
def __init__(self, n, a):
self._name = n
self._age = a
def main():
p = Person('James', 22)
print(p.__dict__)
p.len = 178
p.adr = 'Korea'
print(p.__dict__)
main()
- 객체 내에는 __dict __이 있으며 이는 딕셔너리이다
- __dict __에는 해당 객체의 변수 정보가 담긴다
# prt_dict.py
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 \n 20: your
- __dict __의 정보를 수정함으로써 객체 내 변수의 값을 수정 가능하다
- 객체 내에 있는 변수의 값은 사실 __dict __를 통해서 관리 된다
- sp.n += 10과 sp.__dict _['_n'] += 10은 동일하다
# person_dict3.py
class Person:
def __init__(self, n, a):
self.__name = n
self.__age = a
def main():
p = Person('James', 22)
print(p.__dict__)
main() # {'_Person_name':'James', '_Person__age':22}
- __AttrName => _ClassName __AttrName으로 수정되었다
- 즉 변수 이름에 언더바 2개를 붙이면 파이썬은 위의 패턴대로 이름을 바꾸어 버린다
- 그래서 객체 외부에서 접근이 불가했던 것
- 하지만 바뀐 이름으로 접근한다면 그 접근까지 막진 못한다
'프로그래머 > Python' 카테고리의 다른 글
[윤성우의 열혈 파이썬 중급편] 30. property (0) | 2020.12.24 |
---|---|
[윤성우의 열혈 파이썬 중급편] 29. __slots __의 효과 (0) | 2020.12.24 |
[윤성우의 열혈 파이썬 중급편] 27. 연산자 오버로딩 (0) | 2020.12.24 |
[윤성우의 열혈 파이썬 중급편] 26. 스페셜 메소드 (0) | 2020.12.24 |
[윤성우의 열혈 파이썬 중급편] 25. isintance 함수와 object 클래스 (0) | 2020.12.24 |