getter, setter
- 객체의 내부 변수에 접근할 때 특정 메서드를 거쳐서 접근할 수 있도록 하는 방법
1. decorator 사용
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:
new_pw = input('insert new password : ')
self.hidden_pw = new_pw
else:
print('wrong password')
2. property 메서드 사용
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)
위의 두 코드는 아래와 동일한 출력을 낸다.
setter
person = Person('abcd')
person.pw = 'qwer'
>>
setter
insert password : abcd
insert new password : qwer
getter
person.pw
>>
getter
qw****
mangling
- 변수가 직접적으로 접근하는 것을 막는 방법
- 변수명 앞에 __를 붙임
위에 작성한 코드에서 hidden_pw값을 숨기고 싶을때 아래와 같이 앞에 __를 붙여준다
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)
실행하면 아래와 같이 에러가 발생한다.
person = Person('abcd')
person.__hidden_pw
>> AttributeError: 'Person' object has no attribute '__hidden_pw'
dir(person)
>>
['_Person__hidden_pw',
'__class__',
.
.
'getter',
'pw',
'setter']
즉 mangling 적용시 속성의 이름이 _class명__변수명 으로 변경된다는 것을 알 수 있다.
그러나 아래와 같이 접근하면 접근이 가능하기에 완전히 외부에서의 접근을 막아준다고는 할 수 없다.
-> 그냥 접근을 조금 더 번거롭게 할 뿐 완벽하게 보호해주지는 못한다.
person._Person_hidden_pw = 'aaaa'
person._Person_hidden_pw
>> 'aaaa'
메서드의 종류
- 인스턴스 메서드 : 파라미터 self : 객체를 이용하여 메서드 호출
- 클래스 메서드 : 파라미터 cls : 클래스를 이용하여 메서드 호출 : 객체로 생성된 초기 변수값을 모두 수정
- 스태틱 메서드 : 파라미터 X : 객체를 선언하지 않고 메서드 호출
class Account:
interest = 1.01 # 이자율 1%
def __init__(self, asset = 10000):
self.asset = asset
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(self)
def add_interest(self):
self.asset = int(self.asset * self.interest)
self.__show_asset(self)
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
>>(30000, 20000, 30000, 1.09, 1.04, 1.04)
인스턴스 메서드 사용
account1.change_interest(1.09)
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
>> (10000, 20000, 30000, 1.09, 1.01, 1.01)
클래스 메서드 사용
-> 해당 클래스로부터 만들어진 객체의 변수를 한꺼번에 변경할 때 사용
account1은 위의 코드를 통해 인스턴스를 향하고 있지만, account2 와 account3은 Account 클래스의 interest를 향하고 있기 때문에 두개만 바뀐것을 볼 수 있다.
Account.cls_change_interest(1.04)
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
>>(10000, 20000, 30000, 1.09, 1.04, 1.04)
스태틱 메서드 사용
- 클래스 메서드, 스태틱 메서드의 차이 : 클래스 메서드는 클래스의 변수에 접근이 가능하다.
Account.interest_grade(account1.interest)
Account.interest_grade(account2.interest)
Account.interest_grade(account3.interest)
>>high interest
middle interest
middle interest
클래스 설계
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)
person = Person('peter', 'peter@gmail.com')
person.name, person.email
>> ('peter', 'peter@gmail.com')
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)
name_obj = Name('peter')
email_obj = Email('peter@gmail.com')
person = Person(name_obj, email_obj)
person.show()
>> peter peter@gmail.com
'Python' 카테고리의 다른 글
[Python] 기초 문법 - 모듈, 패키지 (0) | 2023.01.06 |
---|---|
[Python] 기초 문법 - 입출력 (0) | 2023.01.06 |
[Python] 기초 문법 - 클래스(1) (0) | 2023.01.05 |
[Python] 네이버 파파고 번역 API 사용하기 (0) | 2023.01.04 |
[Python] 기초 문법 - 함수 (0) | 2023.01.04 |