Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 게터(Getter)와 세터(Setter) 완벽 정리 – 캡슐화부터 @property 활용까지

대부분의 객체지향 언어는 데이터 캡슐화(data encapsulation)를 위해 게터(getter)와 세터(setter) 메서드를 사용합니다. 그 이유는 객체 클래스의 속성을 외부 클래스로부터 숨겨서, 다른 클래스의 메서드가 실수로 데이터를 변경하는 상황을 방지하기 위해서입니다.

게터와 세터란 무엇인가?

이름 그대로 게터(getter)는 클래스 내부의 프라이빗(private) 속성에 접근하거나 그 값을 가져오는 역할을 하는 메서드이고, 세터(setter)는 프라이빗 속성의 값을 변경하거나 새로 설정하는 역할을 하는 메서드입니다. 파이썬은 다른 언어처럼 문법 차원에서 접근 제한을 강제하지 않지만, 네이밍 규칙과 프로퍼티(property)를 통해 사실상 동일한 캡슐화 패턴을 구현할 수 있습니다.

게터 없이 속성에 접근하기

먼저 별도의 메서드 없이 클래스를 생성하고, 초기화한 뒤 변수에 직접 접근하는 코드를 살펴보겠습니다.

예제

class year_graduated:
    def __init__(self, year=0):
        self._year = year

# 클래스 인스턴스 생성
grad_obj = year_graduated()
# 객체 자체 출력
print(grad_obj)
# 객체의 속성 출력
print(grad_obj._year)

실행 결과

<__main__.year_graduated object at 0x00F2DD50>
0

첫 번째 print 문은 생성된 객체의 정보를 출력하고, 두 번째 print 문은 프라이빗 속성의 기본값인 0을 출력합니다. 이처럼 언더스코어(_) 하나로 시작하는 속성은 관례상 '외부에서 직접 접근하지 말라'는 의미일 뿐, 실제로는 접근이 가능합니다.

게터와 세터 사용하기

다음 예제에서는 클래스를 만들고 초기화한 후, 각 속성에 대해 게터와 세터 메서드를 추가합니다. 그다음 클래스를 인스턴스화하여 이 메서드들을 통해 변수에 접근합니다. 이렇게 하면 세터 메서드 내부에 검증 로직 등 원하는 처리 로직을 숨길 수 있다는 장점이 있습니다.

예제

class year_graduated:
    def __init__(self, year=0):
        self._year = year

    # getter 메서드
    def get_year(self):
        return self._year

    # setter 메서드
    def set_year(self, a):
        self._year = a

grad_obj = year_graduated()
# setter 사용 전
print(grad_obj.get_year())

# setter 사용 후
grad_obj.set_year(2019)
print(grad_obj._year)

실행 결과

0
2019

set_year() 메서드를 호출하기 전에는 기본값 0이 출력되고, 세터로 2019를 지정한 후에는 해당 값이 반영된 것을 확인할 수 있습니다.

속성을 프라이빗으로 만들기

다음 예제에서는 속성을 진짜 프라이빗으로 만들어 외부 호출 함수가 변수를 조작할 수 없도록 하는 방법을 살펴봅니다. 프라이빗 속성은 오직 클래스 내부의 함수만 조작할 수 있으며, 속성 이름 앞에 밑줄 두 개(__)를 붙이면 프라이빗이 됩니다. 파이썬은 이를 네임 맹글링(name mangling)으로 처리해 외부 접근을 차단합니다.

예제

class year_graduated:
    def __init__(self, year=32):
        self.__year = year

    # getter 메서드
    def get_year(self):
        return self.__year

    # setter 메서드
    def set_year(self, a):
        self.__year = a

grad_obj = year_graduated()
print(grad_obj.get_year())

# 외부에서 프라이빗 속성에 직접 접근 시도
print(grad_obj.__year)

실행 결과

32
AttributeError: 'year_graduated' object has no attribute '__year'

게터 메서드를 통한 접근은 정상적으로 32를 반환하지만, 외부에서 __year에 직접 접근하려고 하면 AttributeError가 발생합니다. 이것이 바로 더블 언더스코어를 사용한 프라이빗 속성의 캡슐화 효과입니다.

@property로 프라이빗 값 읽기

이번에는 getter 메서드를 일일이 작성하지 않고도 property 메서드(@property 데코레이터)를 사용해 프라이빗 속성 값에 접근하는 방법을 알아보겠습니다. @property는 메서드를 마치 속성처럼 사용할 수 있게 해주며, @속성명.setter를 함께 사용하면 세터 기능도 깔끔하게 구현할 수 있습니다.

예제

class year_graduated:
    def __init__(self, year=32):
        self.__year = year

    @property
    def Aboutyear(self):
        return self.__year

    @Aboutyear.setter
    def Aboutyear(self, a):
        self.__year = a

grad_obj = year_graduated()
print(grad_obj.Aboutyear)

grad_obj.Aboutyear = 2018
print(grad_obj.Aboutyear)

실행 결과

32
2018

@property 데코레이터를 사용하면 get_year(), set_year() 같은 별도의 메서드를 호출하지 않고도 일반 속성에 접근하듯 값을 읽고 쓸 수 있습니다. 코드가 훨씬 간결해지면서도 내부 데이터는 여전히 안전하게 보호되므로, 실무에서는 게터·세터 메서드보다 @property 방식이 더 널리 권장됩니다.