파이썬에서는 속성 접근 제어를 위해 크게 두 가지 방법을 사용할 수 있습니다
- Descriptor 프로토콜 (__get__, __set__, __delete__)
- property() 내장 함수 (또는 @property 데코레이터)
이번 글에서는 두 가지 방법을 예제를 통해 비교해보겠습니다.
1. Descriptor 기본 예제
class DescriptorEx1:
def __init__ (self, name='Default'):
self.name = name
def __get__(self, obj, objtype):
return f'Get method called. -> self:{self}, obj:{obj}, objtype:{objtype}, name:{self.name}'
def __set__(self, obj, name):
print('Set method called.')
if isinstance(name, str):
self.name = name
else:
raise TypeError('Name should be string.')
def __delete__(self, obj):
print('Delete method called')
self.name = None
class Sample1(object):
name = DescriptorEx1() # 디스크립터 객체 사용
실행 예시
s1 = Sample1()
# __set__ 호출
s1.name = 'Descriptor Test1'
# __get__ 호출
print(s1.name)
# 타입 에러 발생
# s1.name = 10
실행 결과
Set method called.
Get method called. -> self:<__main__.DescriptorEx1 object at ...>, obj:<__main__.Sample1 object at ...>, objtype:<class '__main__.Sample1'>, name: Descriptor Test1
Descriptor는 클래스 단위에서 속성을 제어할 수 있으며, __get__, __set__, __delete__ 메서드를 직접 구현해야 합니다. 따라서 세밀한 제어가 가능하지만 코드가 다소 장황해질 수 있습니다.
2. property() 메서드 활용 예제
class DescriptorEx2:
def __init__(self, value):
self._name = value
def getVal(self):
return 'Get method called. -> self: {}, name: {}'.format(self, self._name)
def setVal(self, value):
print('Set method called.')
if isinstance(value, str):
self._name = value
else:
raise TypeError('Name should be string')
def delVal(self):
print('Delete method called.')
self._name = None
# property 정의
name = property(getVal, setVal, delVal, 'Property Method Example.')
실행 예시
s2 = DescriptorEx2('Descriptor Test2.')
print(s2.name) # getVal 호출
s2.name = 'SetVal Update!!' # setVal 호출
del s2.name # delVal 호출
실행 결과
Get method called. -> self: <__main__.DescriptorEx2 object at ...>, name: Descriptor Test2.
Set method called.
Delete method called.
property()를 사용하면 메서드 호출을 속성 접근처럼 쓸 수 있어 코드가 간결해집니다.
일반적으로 Pythonic한 방식으로 권장되는 방법이기도 합니다.
Descriptor vs Property 비교
| 구분 | Descriptor | property |
| 선언 위치 | 별도의 클래스로 구현 | 클래스 내부 메서드와 함께 정의 |
| 제어 방식 | __get__, __setl__, __delete__ 직접 구현 | property() 또는 @property 데코레이터 사용 |
| 코드 가독성 | 다소 장황 | 간결 |
| 활용 범위 | 프레임워크, ORM, 라이브러리(세밀한 제어 필요) | 일반적인 속성 캡슐화 |
정리하면
- Descriptor는 Python의 내부 동작 원리를 이해할 때 꼭 알아야 할 개념입니다. (예: property, classmethod, staticmethod 자체도 사실 Descriptor입니다.)
- property는 Descriptor를 간단히 활용할 수 있게 만든 편의 기능이라고 볼 수 있습니다.
- 따라서 실무에서는 property를 주로 사용하고, 프레임워크나 라이브러리 개발 같이 깊은 제어가 필요할 때 Descriptor를 직접 구현합니다.
일반적인 속성 제어 → property 사용
프레임워크 수준의 세밀한 동작 제어 → Descriptor 직접 구현
'파이썬 > 기초 프로그래밍' 카테고리의 다른 글
| 데이터 엔지니어링에서 Enum을 활용한 ETL 파이프라인 설계 (0) | 2025.11.28 |
|---|---|
| 파이썬 Descriptor를 활용한 속성 제어 예제 (0) | 2025.09.15 |
| 파이썬 메타클래스로 커스텀 리스트 만들기 (0) | 2025.09.15 |
| Python type()을 이용한 동적 클래스 생성 가이드 (0) | 2025.09.15 |
| 파이썬 메타클래스(Metaclass) 완전 정리 (0) | 2025.09.15 |