-주민번호 등
클래스 밖에서 접근 못하게 할 변수와 메소드를 정함
변수나 메소드 이름 앞에 언더바 두개 __
변수에 간접 접근할 수 있게 메소드 추가하기(getter/ setter or else)
self.__age = age
self.__resident_id = resident_id
class Citizne:
~
def get_age(self):
return self.__age
def set_age(self, value):
self.__age = value
y= Citizen("young", 18, "123456")
y.set_age(24)
print(y.get_age()) # -> 24 로 바뀜
def authenticate
But
__resident_id
는 한 민감개인정보이기 때문에, getter, setter 메소드를 만들지 않음. 대신 주민 번호를 몰라도 인증은 가능 함 (== True 일 때만)
def authenticate(self, id_field):
""" 본인이 맞는지 확인하는 메소드"""
return self.__resident_id == id_field
생성시 부터 나이에 음수 들어가는 것 막음
def __init(self,age)
self.set_age(age) -> init에 메소드넣음
def set_age(self, value):
"""숨겨놓은 인스턴스 변수 __age의 값을 설정하는 메소드"""
if value < 0:
print("나이는 0보다 작을 수 없다. 기본 값으로 나이를 0설정한다.")
self.__age = 0
else:
self.__age = value
print(dir(y))
모든 변수 및 메소드 이름 확인 가능
__age -> _Citizen__age
로 파이썬이 자동 변경해둠. 이 포맷대로 하면 밖에서도 접근이 가능함.-> In fact, 파이썬은 언어 차원에서 캡슐화를 지원하지 않는다!!!
캡슐화 문화를 따른다.
Warning: 언더바 한개 -> 클래스 밖에서 함부로 접근하지 말라.
믿음으로 개발해요
self._resident_id = resident_id
약속 무시하고 직접 접근해서 개발하다가 클래스 코드가 변경되거나 하면 코드가 망가질 수 있음.
__
언더바 두개 말고 _
언더바 하나와 게터 세터 메소드를 사용하자
캡슐화가 강제는 아니다. 그러나 만약 나중에 변수를 캡슐화하고 싶어지면 어떻게 하나?
@property
def age(self):
print("나이를 리턴합니다")
return self._age
@age.setter
def age(self, value):
print("나이를 설정합니다")
if value < 0:
print("나이는 0보다 작을 수 없다. 기본 값으로 나이를 0설정한다.")
self._age = 0
else:
self._age = value
데코레이터를 쓰면 실행할 때 아래와 같이 메소드를 사용하지 않아도
같은 이름을 가진 에이지 메소드를 실행하라는 의미가 됨
기존의 코드를 모두 수정하지 않아도 _age 변수를 알아서 불러옴
y= Citizen("young", 18, "123456")
print(y.age)
y.age = 30
print(y.age) # -> 30 로 바뀜
(위의 코드에서 _age 쓰지 않은 것 확인)
age는 getter, setter 메소드의 이름
_age는 인스턴스 변수
변수 직접 사용 최소화하도록.
변수를 직접 가져다 쓰면 유지보수가 어려움.
e.g. 술집 출입문 프로그램
class Citizen:
drinking_age = 19
def __init__(self, name, age, resident_id):
self.age = age
def can_drink(self):
return self.age >= Citizen.drinking_age => bool
y.Citizen("yg", 29, "123333")
if y.age + 1 >= Citizen.drinking_age
print("음주 가능")
y.Citizen("yg", 29, "123333")
if y.age + 1 >= Citizen.drinking_age
print("무슨 술을 드시겠습니까?")
def can_drink(self):
return self.age +1 >= Citizen.drinking_age # 메소드에 +1 추가
y.Citizen("yg", 29, "123333")
if y.can_drink():
Print("음주가능")
if y.can_drink():
print("무슨 술을 드시겠습니까?")