십대를 위한 코딩/십대를 위한 파이썬

파이썬 클래스의 캡슐화(Encapsulation)

forSilver 2025. 2. 14. 16:08
반응형

🏛 파이썬 클래스의 캡슐화(Encapsulation) 설명

캡슐화(Encapsulation)객체의 속성을 외부에서 직접 접근하지 못하도록 보호하고, 접근을 제어하는 기능을 의미합니다.
이러한 개념은 **데이터 은닉(Data Hiding)**과 정보 보호를 위해 사용됩니다.

캡슐화 예제

 


1. 예제 코드 분석

📌 사용자가 업로드한 코드(cat_age_with_setter_getter.py)를 보면, 캡슐화의 개념을 적용한 예제입니다.

class Cat:
    def __init__(self, name, age):
        self.__name = name   # ✅ 캡슐화: 변수 앞에 '__' 추가하여 비공개 속성으로 설정
        self.__age = age

    def __str__(self):
        return 'Cat(name = '+self.__name+', age = '+str(self.__age)+')'

    def set_age(self, age):
        if age > 0:   # ✅ 나이를 음수로 설정하지 못하도록 제어
            self.__age = age

    def get_age(self):
        return self.__age

# 객체 생성 및 테스트
nabi = Cat('나비', 3)
print(nabi)         # Cat(name = 나비, age = 3)
nabi.set_age(4)     # 나이를 4로 변경
nabi.set_age(-5)    # 음수 나이 입력 (변경되지 않음)
print(nabi)         # Cat(name = 나비, age = 4)

🛠 실행 결과

Cat(name = 나비, age = 3)
Cat(name = 나비, age = 4)

📌 nabi.set_age(-5)를 호출했지만, 나이가 음수라서 변경되지 않았습니다.
즉, set_age() 메서드를 통해 잘못된 값이 설정되지 않도록 보호하고 있습니다.


2. 캡슐화(Encapsulation)의 개념 적용

(1) __변수명을 사용하여 속성 보호

self.__name
self.__age
  • 변수명 앞에 **__(언더스코어 두 개)**를 붙이면 **비공개 속성(private attribute)**이 됩니다.
  • 이렇게 하면 클래스 외부에서 직접 접근이 불가능합니다.

외부에서 직접 접근 시 오류 발생 예제

print(nabi.__age)  # ❌ AttributeError: 'Cat' object has no attribute '__age'

(2) setter와 getter 메서드로 값 설정 및 접근

외부에서 직접 접근하지 못하는 속성을 변경하거나 조회하기 위해 set_age()와 get_age()를 제공

def set_age(self, age):
    if age > 0:
        self.__age = age  # ✅ 올바른 값만 설정 가능

def get_age(self):
    return self.__age  # ✅ 값을 안전하게 반환

데이터 보호: 잘못된 값(음수)이 입력되지 않도록 제어
안전한 접근: 직접 self.__age를 수정하는 대신 set_age() 메서드를 통해 값 변경

잘못된 값 보호 예제

nabi.set_age(-5)  # ❌ age가 -5이면 변경되지 않음

3. 캡슐화의 장점

장점 설명

데이터 보호 외부에서 속성을 직접 변경할 수 없도록 막음
잘못된 값 방지 setter에서 값 검증을 통해 유효한 데이터만 저장
코드 유지보수성 증가 직접 접근 대신 메서드를 통해 속성을 변경하므로 관리가 쉬움
객체의 일관성 유지 특정 규칙에 따라 값이 변경되도록 설정 가능

4. 캡슐화를 더 개선하는 방법 (property 사용)

파이썬에서는 property 데코레이터를 사용하여 더 깔끔하게 캡슐화를 구현할 수 있습니다.

업그레이드된 코드 (property 사용)

class Cat:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def __str__(self):
        return f"Cat(name = {self.__name}, age = {self.__age})"

    @property
    def age(self):  # ✅ getter 역할
        return self.__age

    @age.setter
    def age(self, value):  # ✅ setter 역할
        if value > 0:
            self.__age = value

# 객체 생성 및 테스트
nabi = Cat('나비', 3)
print(nabi)       # Cat(name = 나비, age = 3)
nabi.age = 4      # ✅ setter를 사용하여 나이 변경
nabi.age = -5     # ❌ 음수 입력 시 변경되지 않음
print(nabi)       # Cat(name = 나비, age = 4)

🏆 property를 사용하면

✅ nabi.age = 4처럼 속성을 다루듯이 setter를 사용할 수 있어 가독성이 좋아진다.
✅ getter와 setter가 더 간결하고 직관적인 코드가 된다.
✅ @property를 사용하면 get_age()와 set_age() 같은 별도의 메서드를 호출할 필요가 없다.


🎯 결론: 캡슐화는 왜 필요한가?

데이터를 보호하고 무결성을 유지하기 위해 사용된다.
클래스 외부에서 속성값을 직접 수정하지 못하도록 제한하여 오류를 줄인다.
getter & setter 또는 @property를 활용하면 보다 안전하게 데이터를 관리할 수 있다.

💡 캡슐화는 객체 지향 프로그래밍(OOP)의 중요한 개념 중 하나로, 코드의 안정성과 유지보수성을 높이는 데 필수적인 기법이다! 🚀🔥