euny!
errorlog
euny!
전체 방문자
오늘
어제
  • 분류 전체보기 (22)
    • Python (13)
    • 데이터분석 (3)
    • WIL (4)
    • SQL (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 웹크롤링
  • ㅗ
  • BeautifulSoup
  • 웹스크래핑
  • SQL
  • 크롤링

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
euny!

errorlog

[Python] 기초 문법 - 클래스(2)
Python

[Python] 기초 문법 - 클래스(2)

2023. 1. 6. 16:24

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
    'Python' 카테고리의 다른 글
    • [Python] 기초 문법 - 모듈, 패키지
    • [Python] 기초 문법 - 입출력
    • [Python] 기초 문법 - 클래스(1)
    • [Python] 네이버 파파고 번역 API 사용하기
    euny!
    euny!

    티스토리툴바