프로그래밍백엔드 개발자

파이썬의 속성 데코레이터(@property)는 무엇이며, 어떻게 캡슐화를 구현하는 데 도움이 되는가? 사용 시 주의해야 할 점은 무엇인가?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 역사:

클래식 OOP에서 캡슐화는 개인 필드와 getter/setter를 통해 구현되지만, 이는 복잡하고 "파이썬스럽지" 않습니다. 파이썬 2.2 버전부터 @property 데코레이터가 도입되어 getter와 setter 메서드에 일반 속성처럼 접근할 수 있어, 우아한 문법으로 효율적인 캡슐화를 구현하게 되었습니다.

문제:

데코레이터 없이 property를 사용하려면 접근 및 값을 설정하기 위해 메서드를 명시적으로 정의해야 합니다(예: get_x()set_x(val)), 이로 인해 코드는 덜 읽기 쉬워지며 클래스 사용자는 내부 데이터에 직접 접근할 위험이 있습니다. 내부 저장 방식이나 값 계산 로직을 변경할 때 문제가 발생합니다.

해결:

@property 데코레이터를 사용하면 하나의 문법으로 getter, setter 및 deleter를 정의할 수 있습니다. 이는 간결하고 편리하며 구현 세부 정보를 캡슐화하고 속성을 계산하는 방식을 변경하더라도 클래스의 인터페이스가 손상되지 않도록 합니다.

코드 예시:

class Temperature: def __init__(self, celsius): self._celsius = celsius @property def celsius(self): return self._celsius @celsius.setter def celsius(self, value): if value < -273.15: raise ValueError("-273.15°C 이하의 온도는 불가능합니다!") self._celsius = value

주요 특징:

  • @property 데코레이터는 메서드에 일반 속성처럼 접근할 수 있게 해줍니다.
  • 검증 또는 캐싱 로직을 쉽게 추가할 수 있습니다.
  • 인터페이스 변경 없이 로직을 변경할 수 있어, 클래스 사용자는 변화를 인식하지 못하게 됩니다.

함정 질문.

읽기 전용 속성을 만들 수 있지만, 쓰기/삭제는 할 수 없나요?

네, @property 데코레이터가 있는 메서드만 정의하고 setter와 deleter를 정의하지 않으면, 해당 속성은 읽기 전용으로 제공됩니다.

class Sample: @property def value(self): return 42

property 이름이 개인 속성과 중복되면 어떻게 되나요?

보통 property는 개인 속성에 대한 "레이어"로 사용되며, 해당 이름은 언더스코어로 시작합니다(예: _x). 이러한 중복은 피해야 하며, 그렇지 않으면 재귀 호출이 발생할 수 있습니다:

class Bad: @property def x(self): return self.x # 무한 재귀

클래스에만 property를 지정할 수 있나요?

아니요, 표준 @property는 클래스의 인스턴스와 함께 작동합니다. 클래스 속성을 만들려면 외부 패턴이나 특별한 라이브러리를 사용해야 하며(@classmethod와 함께 property는 직접 작동하지 않습니다).

일반적인 오류 및 안티 패턴

  • 속성 이름을 잘못 정의(예: property와 내부 필드의 이름 중복).
  • 잘못 구현된 setter로 인해 재귀 호출 발생.
  • 계산/검증이 필요 없는 속성에 property를 남용.

실제 예시

부정적인 케이스

개발자가 클래스 필드(self.celsius)에 직접 접근하여 property를 사용하지 않습니다. 나중에 검증 로직이 추가되지만, 클래스 사용자들은 여전히 개인 속성을 직접 수정하여 검증을 우회할 수 있습니다.

장점:

복잡한 로직이 없을 때 쉽고 빠르게 작업할 수 있습니다.

단점:

캡슐화가 훼손되어 객체의 잘못된 상태를 얻기 쉬워지고 혼란이 발생할 수 있습니다.

긍정적인 케이스

property를 사용하고 내부 속성을 _celsius를 통해 숨깁니다. 검증, 캐싱 및 로직이 property 내부에 중앙 집중화됩니다.

장점:

코드가 보호되고 인터페이스가 안정적입니다 — 속성 구현을 변경하더라도 클래스 사용자에게 영향이 없습니다.

단점:

크고 복잡한 객체의 경우 property를 지나치게 사용하면 디버깅의 복잡성이 증가할 수 있습니다.