비공개 속성
비공개 속성(private attributes)이란 클래스 외부에서 접근할 수 없는 속성을 의미합니다. 속성 이름 앞에 밑줄을 두 개 붙이면 비공개 속성이 됩니다. 다음 예제 코드에서 SoccerTeam이라는 클래스 안에 self.__win_weight, self.__draw_weight, self.__lose_weight가 비공개 필드입니다.
class SoccerTeam:
def __init__(self, name, win, draw, lose):
self.name = name
self.win = win
self.draw = draw
self.lose = lose
self.__win_weight = 3
self.__draw_weight = 1
self.__lose_weight = 0
self.win_pts = 0
def cal_pts(self):
self.win_pts = self.__win_weight * self.win + self.__draw_weight * self.draw + self.__lose_weight * self.lose
team1 = SoccerTeam('아스날', 16, 2, 1)
team1.cal_pts()
print(team1.win_pts)
print(team1.win, team1.draw, team1.lose)
print(team1.__win_weight)
다른 공개 속성과는 달리 클래스 외부에서 접근하고자 하면 에러가 발생합니다.
존재하지 않는 속성이라고 에러 메시지를 띄워줍니다. 실제로는 존재하지만 말이죠.
게터, 세터
이러한 비공개 속성의 값을 확인하고 싶거나, 값을 변경하고 싶을 때는 메소드를 활용할 수 있습니다. 값을 얻기 위해 사용되는 메소드를 보통 게터(getter)라고 하고, 값을 변경하기 위해 사용되는 메소드를 세터(setter)라고 합니다. 승리 가중치 변수의 값을 얻고, 수정하는 게터와 세터를 만들어보겠습니다.
class SoccerTeam:
def __init__(self, name, win, draw, lose):
self.name = name
self.win = win
self.draw = draw
self.lose = lose
self.__win_weight = 3
self.__draw_weight = 1
self.__lose_weight = 0
self.win_pts = 0
def cal_pts(self):
self.win_pts = self.__win_weight * self.win + self.__draw_weight * self.draw + self.__lose_weight * self.lose
def get_win_weight(self):
return self.__win_weight
def set_win_weight(self, new_win_weight):
self.__win_weight = new_win_weight
team1 = SoccerTeam('아스날', 16, 2, 1)
team1.cal_pts()
print(f"승점: {team1.win_pts}")
print(team1.get_win_weight())
team1.set_win_weight(5)
team1.cal_pts()
print(f"승점: {team1.win_pts}")
게터와 세터 덕분에 비공개 속성의 값을 얻고, 변경할 수 있게 되었습니다. 새로운 승리 가중치로 인해, 다시 계산한 승점도 변경된 것을 확인하실 수 있습니다.
@property
비공개 속성의 값을 얻고 수정하는 간단한 일을 위해 게터, 세터를 위와 같은 방식으로 만드는 것이 조금 번거롭게 느껴지실 수도 있겠습니다. @property 데코레이터를 활용하면 조금 더 간편하게 게터와 세터를 선언할 수 있습니다.
class SoccerTeam:
def __init__(self, name, win, draw, lose):
self.name = name
self.win = win
self.draw = draw
self.lose = lose
self.__win_weight = 3
self.__draw_weight = 1
self.__lose_weight = 0
self.win_pts = 0
def cal_pts(self):
self.win_pts = self.__win_weight * self.win + self.__draw_weight * self.draw + self.__lose_weight * self.lose
# 게터
@property
def win_weight(self):
return self.__win_weight
# 세터
@win_weight.setter
def win_weight(self, new_win_weight):
self.__win_weight = new_win_weight
team1 = SoccerTeam('아스날', 16, 2, 1)
team1.cal_pts()
print(f"승점: {team1.win_pts}")
print(team1.win_weight)
team1.win_weight = 5
team1.cal_pts()
print(f"승점: {team1.win_pts}")
게터로 사용될 메소드 위에는 @property 데코레이터를 붙여주고, 세터로 사용될 메소드 위에는 @속성명.setter 데코레이터를 붙여줍니다. 이제는 원래 인스턴스 속성 값을 얻고 변경하는 것처럼 사용할 수 있게 되었습니다.
참고자료
[1] https://www.youtube.com/watch?v=l8PoJ1kJQjA
[2] 브렛 슬라킨 지음, 오현석 옮김, "파이썬 코딩의 기술", 길벗
'Dev > python' 카테고리의 다른 글
[Flask] Flask API 서버에 인증 기능 넣기 (0) | 2023.02.19 |
---|---|
[flask] ModuleNotFoundError: No module named 'wtforms.fields.html5' 에러 해결 방법 (2) | 2023.01.31 |
[python] 클래스 속성과 클래스 메서드 (0) | 2023.01.28 |
[python] 정적 메서드(static method)는 주로 어떤 경우에 사용되는가 (0) | 2023.01.27 |
[python] 약수 구하는 알고리즘 (0) | 2023.01.26 |
[python] 클래스 안에 __로 시작하고 __로 끝나는 메소드들, 매직 메소드(magic method) (0) | 2023.01.25 |
[python] 제너레이터의 필요성(메모리 효율성) (0) | 2023.01.16 |
[pandas] 데이터프레임의 행들을 반복문에서 얻고 싶다면, df.iterrows() (0) | 2023.01.14 |