관리 메뉴

커리까지

캡슐화 본문

Python

캡슐화

목표는 커리 2021. 5. 12. 17:49
728x90
SMALL

www.youtube.com/watch?v=ALihnmMmF70

class CreditCard:
    MAX_PAYMENT_LIMIT = 30000000

    # 인스턴스 변수 앞에 던더를 붙이면 변수를 숨긴다.
    def __init__(self, name, password, payment_limit):
        self.__name = name
        self.__password = password
        self.__payment_limit = payment_limit

    def get_name(self):
        return self.__name

    def set_name(self, new_name):
        self.__name = new_name

    def get_password(self):
        return "Can not display"

    def set_password(self, new_password):
        self.__password = new_password

    def get_payment_limit(self):
        return self.__payment_limit

    def set_payment_limit(self, new_payment_limit):
        self.__payment_limit = new_payment_limit

    def set_payment_limit(self, new_payment_limit):
        if new_payment_limit >= 0 and new_payment_limit <= MAX_PAYMENT_LIMIT :
            self.__payment_limit = new_payment_limit
        else:
            print('The limit should be betwwen 0 and 3 million.')

card = CreditCard('kang', '1234', 100000)

print(card.get_name())
print(card.get_password())
print(card.get_payment_limit())

card.set_name('kim')
card.set_password('111')
card.set_payment_limit(-10)

print(card.get_name())
print(card.get_password())
print(card.get_payment_limit())
  • 인스턴스 변수 앞에 던더를 붙이면 변수를 숨긴다.
  • 접근할 수 있는 변수를 숨겼으니 접근할 수 있는 getter와 setter을 만든다.
@property
def password(self):
    return "Can not display"
  • 위에 데코레이터를 붙이면 getter가 생성이 된것이다.
def set_password(self, new_password):
    self.__password = new_password

@password.setter
def password(self, new_password):
    self.__password = new_password
  • 이렇게 바꿔주면 setter가 생성된 것이다.
class CreditCard:
    MAX_PAYMENT_LIMIT = 30000000

    # 인스턴스 변수 앞에 던더를 붙이면 변수를 숨긴다.
    def __init__(self, name, password, payment_limit):
        self.name = name
        self.__password = password
        self.__payment_limit = payment_limit

    @property
    def password(self):
        return "Can not display"

    @password.setter
    def password(self, new_password):
        self.__password = new_password

    @property
    def payment_limit(self):
        return self.__payment_limit

    @payment_limit.setter
    def payment_limit(self, new_payment_limit):
        if new_payment_limit >= 0 and new_payment_limit <= MAX_PAYMENT_LIMIT :
            self.__payment_limit = new_payment_limit
        else:
            print('The limit should be betwwen 0 and 3 million.')

card = CreditCard('kang', '1234', 100000)

print(card.name)
print(card.password)
print(card.payment_limit)

card.name = 'kim'
card.password = '111'
card.payment_limit = -10

print(card.name)
print(card.password)
print(card.payment_limit)
  • card.get_name()card.name() 으로 바꿔준다. 아까는 숨겼지만 지금은 숨기지 않았기 때문에 그냥 선언한다.
card.set_name('kim')
card.set_password('111')
card.set_payment_limit(-10)

----------------------------

card.name = 'kim'
card.password = '111'
card.payment_limit = -10
  • 데코레이터를 붙였기 때문에 그냥 선언하면 된다.
  • 보통 던더+변수명 하면 private로 설정되어 클래스 내부에서만 접근 가능해진다.
  • 던더를 적으면 파이썬에서는 해당 변수 또는 메서드명의 네임 맹글링이 발생한다.
던더+변수
__user

_클래스명__변수
_User__name
  • 네임 맹글링 룰을 알고있는개발자라면 숨긴 변수에 접근해서 사용할 수 있다는 단점이 있다.(물론 이렇게 하는 개발자는 없다.)
  • 파이썬에서는 특별한 접근 제어자가 없고 네임맹글링 룰을 알고 있는 개잘바는 언제든 접근이 가능한 단점이 있다. (강제할 방법이 없다)

public을 실현하는 법

  • 접두사에 마무 밑줄이 없다.
  • 전역에서 접근 가능

private를 실현하는 법

  • 접두사에 두 개의 밑줄(__)을 적용
  • 해당 클래스 내에서만 접근 가능

protected를 실현하는 법

  • 접두사에 한 개의 밑줄(_)을 적용
  • 해당 클래스 및 클래스를 상속한 자식 클래스에서 접근 가능

default를 실현하는 법

  • 파이썬에는 존재하지 않는다.
  • 해당 모듈, 패키지 안에서만 접근 가능

캡슐화2

class Person:
    DEFAULT_LIMIT_AGE = 19

    def __init__(self, name, age):
        self.name = name
        self.age = age

class Hof:
    @staticmethod
    def check_age(person):
        return person.age >= 19


class Pub:
    @staticmethod
    def check_age(person):
        return person.age >= 19


person1 = Person("kim", 20)
person2 = Person("lee", 18)

print(Hof.check_age(person1))
print(Hof.check_age(person2))
  • 이렇게 작성하면 캡슐화가 깨진것이다. 왜냐하면 제한 나이가 내려가거나 올라가면 Hof와 Pub를 각각 직접 수정해야 한다.
  • 캡슐화는 객체의 속성과 그것을 사용하는 행동을 하나로 묶는 것이다.
class Person:
    DEFAULT_LIMIT_AGE = 19

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def check_age(self):
        return self.age >= Person.DEFAULT_LIMIT_AGE

class Hof:
    pass


class Pub:
    pass


person1 = Person("kim", 20)
person2 = Person("lee", 18)

print(person1.check_age())
print(person2.check_age())
  • 이렇게 작성해야 캡슐화가 유지된 것이다.
728x90
LIST
Comments