뒤죽박죽 데이터분석 일기장
[Python] [5일차] Class 파트 2 본문
안녕하세요. 이번 포스트는 저번 포스트에 이어서 클래스에 대해 더 알아보려고 합니다.
우선, 프로퍼티에 대해서 복습하려고 합니다.
getter 와 setter 이 두 가지 메서드가 있는데요.
getter | 값을 가져오는 메서드 |
setter | 값을 저장하는 메서드 |
파이썬에서는 @property 라는 데코레이터를 사용해 구현할 수 있습니다.
- @property
- @메서드이름.setter
이제 예시를 들어서 확인해 보겠습니다.
비밀번호를 입력하고 수정하는 class를 getter와 setter 메서드로 표현해 보겠습니다.
class Person:
def __init__(self, pw):
self.hidden_pw = pw
#getter
@property
def pw(self):
print('getter')
return self.hidden_pw
#setter
@pw.setter
def pw(self, pw):
print('setter')
self.hidden_pw = pw
person = Person('abcd') # 비밀번호 대입/ 객체선언
setter 메서드로 수정하기:
person.pw = 'qwer'
이제 setter 메서드로 새로운 패스워드가 시스템에 입력되었는지 getter 메서드를 통해서 알아보겠습니다.
person.pw
결과:
보시면 getter 메서드로 출력한 결과 성공적으로 수정되었습니다.
하지만, 비밀번호가 저렇게 쉽게 변경되면 문제가 생기겠죠?
그래서 우리는 위 함수를 응용해서 이미 입력되어 있는 비밀번호를 입력해야 비밀번호를 변경할 수 있는 클래스를 만들어 보겠습니다.
class Person:
def __init__(self, pw):
self.hidden_pw = pw
@property
def pw(self):
print('getter')
return self.hidden_pw[:2] + '****'
@pw.setter
def pw(self, new_pw):
print('setter')
input_pw = input('insert password : ')
if input_pw == self.hidden_pw:
self.hidden_pw = new_pw
else:
print('wrong password!')
person = Person('abcd') #초기 비밀번호 값/ 객체 선언
위의 클래스의 코드를 완성하고 객체 선언을 해서 초기 비밀번호를 'abcd'로 설정했습니다.
그럼, 아까 했던 거와 마찬가지로 setter 메서드를 이용해서 값을 변경해 보겠습니다.
person.pw = 'qwer'
결과:
이런 식으로 잘못된 초기 비밀번호를 입력하면 비밀번호 값을 수정할 수 없습니다. 이렇게 비밀번호의 보안성을 유지할 수 있습니다.
또한 getter 메서드로 비밀번호를 출력하려고 하면
person.pw
결과:
이런식으로 마스킹되서 출력됩니다.
하지만 사실 비밀번호를 출력할 수 있습니다.
바로 진짜 패스워드가 저장되어 있는 식별자의 이름을 알면 파악할 수 있습니다.
person.hidden_pw='qqqq'
이렇게 식별자의 이름을 알면 바로 바꿀 수 있습니다.
mangling
따라서 이런 오류까지 방지하기 위해서 mangling 이라는 개념 적용시켜보겠다.
mangling 이란 변수에 직접적으로 접근하는 것을 막는 방법이다.
사용하는 방법은 변수명 앞에 __, 즉 로우대시 두개를 붙인다.
이렇게 되면 위의 구문처럼 직접적으로 바꾸는 것은 불가능해지지만 원래 함수대로 비밀번호 값을 제대로 입력한다면 값을 변경할 수 있다.
class Person:
def __init__(self, pw):
self.__hidden_pw = pw
def getter(self):
print('getter')
return self.__hidden_pw
def setter(self, new_pw):
print('setter')
input_pw = input('insert password : ')
if input_pw == self.__hidden_pw:
self.__hidden_pw = new_pw
else:
print('wrong password!')
pw = property(getter, setter)
메서드의 종류
이번엔 클래스 안에 있는 메서드의 종류에 대해서 복습해 보려고 한다.
메서드는 총 3가지로 분류되어 있는데 : 인스턴스 메서드, 클래스 메서드, 스태틱 메서드로 나뉘어져 있다.
1. 인스턴스 메서드
: 파라미터 self : 객체를 이용해서 매서드 호출
2. 클래스 메서드
: 파라미터 cls : 클래스를 이용하여 메서드 호출 : 객체로 생성된 초기 변수값을 모두 수정
3. 스태틱 매서드
: 파라미터 x : 객체를 선언하지 않고 매서드 호출
이번에는 이자율을 계산하는 클래스 안에 위의 3가지 메서드를 포함해 비교하면 설명해보겠습니다.
class Account:
interest = 1.01 #이자율 1프로
def __init__(self, asset=10000):
self.asset = asset
def deposit(self, amount):
self.asset += amount
def withdraw(self, amount):
if self.asset >= amount:
self.asset -= amount
else:
print('total asset', self.asset)
def add_interest(self):
self.asset = int(self.asset * self.interest)
print('total asset', self.asset)
# 이자율을 변경해주는 인스턴스 매서드
def change_interest(self, interest):
if interest <= 1.10:
self.interest = interest
else:
print("이자율을 10% 미만으로 설정해주세요.")
@classmethod
def cls_change_interest(cls, interest):
if interest <= 1.10:
cls.interest = interest
else:
print("이자율을 10% 미만으로 설정해주세요.")
@staticmethod
def interest_grade(interest):
if interest > 1.05:
print('high interest')
elif interest > 1.02:
print('middle interest')
else:
print('low interest')
객체 선언:
account1 = Account(10000)
account2 = Account(20000)
account3 = Account(30000)
#출력
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
결과:
객체선언 후 출력해 본 결과 아래와 같이 입력된 잔고와 현재 이자율을 확인할 수 있다.
1. 인스턴스 메서드를 사용해서 이자율을 변경해보겠다.
account1.change_interest(1.09)
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
결과:
설명:
인스턴스 메서드를 이용해 account1의 이자율을 변경하였다.
2. 클래스 매서드 사용
Account.cls_change_interest(1.04)
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
결과:
설명:
모든 이자율 기초값이 1.04로 변경되었다. 하지만 account1의 이자율은 변경되지 않았다. 그 이유는 인스턴스 매서드로 직접 변경된 값은 클래스 매서드를 사용해도 주소값이 다르기 때문에 변하지 않는다.
3. 스태틱 매서드 사용
Account.interest_grade(account1.interest)
Account.interest_grade(account2.interest)
결과:
설명:
클래스 매서드와 스태틱 매서드의 차이는 클래스 매서드는 클래스의 변수에 접근이 가능하지만 반대로 스태틱 메서드는 그렇지 않다.
TIP: 아까 배운 mangling 개념도 똑같이 적용시킬 수 있다.
class Account:
interest = 1.01 # 이자율 1%
def __init__(self, asset=10000):
self.asset = asset
#함수 mangling
def __show_asset(self):
print('total asset', self.asset)
def deposit(self, amount):
self.asset += amount
def withdraw(self, amount):
if self.asset >= amount:
self.asset -= amount
else:
self.__show_asset()
def add_interest(self):
self.asset = int(self.asset * self.interest)
self.__show_asset()
def change_interest(self, interest):
if interest < 1.10:
self.interest = interest
else:
print('이자율을 10% 미만으로 설정해주세요.')
@classmethod
def cls_change_interest(cls, interest):
if interest < 1.10:
cls.interest = interest
else:
print('이자율을 10% 미만으로 설정해주세요.')
@staticmethod
def interest_grade(interest):
if interest > 1.05:
print('high interest')
elif interest > 1.02:
print('middle interest')
else:
print('low interest')
@classmethod
def cls_change_interest(cls, interest):
if interest <= 1.10:
cls.interest = interest
else:
print("이자율을 10% 미만으로 설정해주세요.")
@staticmethod
def interest_grade(interest):
if interest > 1.05:
print('high interest')
elif interest > 1.02:
print('middle interest')
else:
print('low interest')
클래스 설계: is a, has a 개념
is a
: A is a B
: 상속을 이용하여 클래스 설계
has a
: A has a B
: 객체를 객체에 넣어서 클래스 설계
첫번째, is a 개념을 이용한 클래스 설계 예제
# is a
class Info:
def __init__(self, name, email):
self.name = name
self.email = email
class Person(Info):
def show(self):
print(self.name,self.email)
처음에 Info 클래스 생성 후 밑에 Person 클래스의 상속시킨다.
person = Person('peter', 'peter@gmail.com')
person.name, person.email
결과:
두번째, has a 개념을 이용한 클래스 설계 예제
처음에 두 개의 클래스를 생성해줍니다.
# has a
class Name:
def __init__(self, name):
self.name_str = name
class Email:
def __init__(self, email):
self.email_str = email
설명: 이름과 이메일을 할당하는 두 개의 함수입니다.
class Person:
def __init__(self, name_obj, email_obj):
self.name = name_obj
self.email = email_obj
def show(self):
print(self.name.name_str, self.email.email_str)
그러고 Person이라는 하나의 클래스를 생성해서 출력되는 프로그램을 생성해 줍니다.
그 이후에 우선 처음에 만들었던 2개의 클래스의 객체선언을 해줍니다.
name_obj = Name('peter')
email_obj = Email('peter@gmail.com')
그러고 이전에 선언했던 Person class에 대입해줍니다.
person = Person(name_obj, email_obj)
person.show()
결과:
'Python' 카테고리의 다른 글
[Python] [5일차] 모듈과 패키지 (0) | 2023.01.07 |
---|---|
[Python] [5일차] 입출력, 파일 저장 및 출력 (0) | 2023.01.07 |
[Python] [4일차] Class 파트 1 (0) | 2023.01.05 |
[Python] [강의 3일차] 함수 (0) | 2023.01.04 |
[Python] [2일차] 조건문, 반복문 (2) | 2023.01.03 |