Python에서의 캡슐화

Python에서의 캡슐화

Python 캡슐화는 객체의 내부 세부 정보를 숨기고 필요한 정보와 기능만 노출하는 방법입니다.

캡슐화는 클래스 특성 및 메서드의 가시성을 제어하는 특수 키워드인 access modifiers를 사용합니다.

Python에서의 3가지 access modifiers

  • Public : Public 속성과 메서드는 클래스 내부, 외부 어디에서나 접근할 수 있습니다. Python에서는 모든 속성과 메소드가 기본적으로 공개됩니다.
  • Protected : Protected 속성과 메서드는 하나의 언더바(_)로 표시합니다. 클래스 및 하위 클래스 내에서는 접근할 수 있지만, 클래스 계층 구조 외부에서는 접근할 수 없습니다.
  • Private : Private 속성과 메서드는 두 개의 언더바(__)로 표시합니다. 정의한 클래스 내에서만 접근할 수 있으며, 하위 클래스나 클래스 외부에서는 접근할 수 없습니다.

private 예제

source code

class BankAccount:
    def __init__(self, account_number: str, balance: int) -> None:
        self.__account_number: str = account_number
        self.__balance: int = balance

    def deposit(self, amount: int) -> None:
        self.__balance += amount

    def withdraw(self, amount: int) -> None:
        if amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Insufficient funds")

    def get_balance(self) -> int:
        return self.__balance

# bank account 객체 생성
my_account = BankAccount("123456789", 1000)

# 계좌번호 속성에 직접 접근 시도(실패)
# print(my_account.__account_number)  # AttributeError: 'BankAccount' object has no attribute '__account_number'

# public method를 사용해 입금
my_account.deposit(500)

# 출금 불가능한 금액 출금 시도 (실패)
my_account.withdraw(2000)       # Insufficient funds

# public method를 활용해서 현재 잔액 get
print(my_account.get_balance())     # 1500

# 이렇게 접근 가능
print(my_account._BankAccount__account_number)   # 123456789

name mangling variable

__acount_number와 같이 언더 바가 앞에 2개인 변수를 name magling variable이라고 합니다.

아래 글에 name mangling에 대해서 매우 잘 정리해주셨습니다. 아래 글을 참고하시면 아래 내용 이해하는데 큰 도움이 되실겁니다.
name magling varialbe 관련 글

이러한 name magling 방식으로 변수를 선언하면 이 변수는 클래스에 private 변수가 됩니다.
그래서 위의 글 처럼 외부에서 접근이 어렵습니다.

다만, 접근이 어려울 뿐이지 외부에서 접근을 업격하게 제한하는 것은 아닙니다. 다시말해, 접근은 할 수 있습니다.(위의 글에서도 나오는 내용입니다.)

name mangling을 적용한 변수에 파이썬 인터프리터는 자동으로 변수 이름을 _classname__variable로 바꿉니다. 여기서 classname은 클래스 이름이고, variable은 변수 이름입니다.
위의 예시를 보면 __acount_number는 파이썬 인터프리터에 의해 _BankAccount__account_number로 바뀌는 것입니다. 그래서

print(my_account._BankAccount__account_number)   # 123456789

이 코드로 접근이 가능한 것입니다.

이처럼 name mangling variable은 파이썬의 관례일뿐이지, 여전히 변수에 엑세스 할 수 있습니다.

Protected 예제

soruce code

class MyClass:
    def __init__(self) -> None:
        self._protected_variable = 42


class MySubClass(MyClass):
    def __init__(self) -> None:
        super().__init__()
        print(self._protected_variable)     # 42


# 객체 생성
obj1 = MyClass()
obj2 = MySubClass()

# protected 변수 직접 접근
print(obj1._protected_variable)     # 42

# 외부에서 protected 변수 접근 시도
print(obj2._protected_variable)     # 42

위의 예시처럼 MyClass와 MySubClass 객체를 생성할 때 _protected_variable에 직접 엑세스 할 수 있습니다. 그러나 클래스 외부에서 이 변수를 접근할 경우는 에러가 발생합니다.

'Python > Python' 카테고리의 다른 글

Python 라이브러리 - re  (0) 2023.05.11
Python 라이브러리 - textwrap  (1) 2023.05.10
Subtype in Python  (0) 2023.03.30
First Class Function  (0) 2023.03.30
파이썬에서 Function과 method의 차이  (0) 2023.03.20