파이썬에서 데코레이터 @property는 "가상" 속성을 만들 수 있게 해줍니다 — 일반 필드처럼 보이고 사용되지만, getter, setter 또는 deleter 로직을 실행하는 메서드입니다. 이는 계산된 속성을 생성하거나 데이터 접근을 제어하는 데 유용합니다.
예시:
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): if value <= 0: raise ValueError('너비는 양수여야 합니다') self._width = value r = Rectangle(3, 4) print(r.area) # 12 (속성처럼 호출됨, 함수가 아님) r.width = 10 # setter가 자동으로 호출됨
@property (getter 메서드)만 사용하고 setter를 정의하지 않을 수 있나요? 그런 속성을 변경하려고 하면 무엇이 발생하나요?
답변: ggetter @property만 정의할 수 있으며 setter(및 deleter)는 정의할 필요가 없습니다. 이 속성은 읽기 전용이 되며, 할당을 시도하면 AttributeError가 발생합니다.
class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: 속성을 설정할 수 없습니다
이야기
표준 라이브러리를 사용하여 객체를 직렬화하려고 시도하는 과정에서 vars(obj)를 이용해 속성 사전을 얻으려고 했습니다. 그러나 property 메서드는 __dict__ 출력에 포함되지 않아서 그 값이 직렬화되지 않아 데이터 유출이 발생했습니다.
이야기
프로젝트에서 property에 대한 setter를 추가하는 것을 잊어버려서, 결과적으로 계산된 필드의 값을 변경하려는 시도가 런타임 오류를 일으켰고, 이는 아키텍처의 논리적으로는 예상된 상황이었습니다.
이야기
작동 중인 코드에서 property 값을 계산할 때 무거운 작업이나 안전하지 않은 작업이 허용되었고, 이는 속성에 접근할 때마다 예기치 않게 호출되었습니다. 이는 성능을 저하시켰고 멀티스레드 코드에서 차단 호출로 이어졌습니다.