개요
파이썬 디스크립터는 객체의 속성 접근을 제어하는 강력한 도구입니다. 이 디스크립터의 핵심에는 __get__과 __set__ 같은 특별한 메서드들이 있습니다. 팀원과의 대화에서 던져진 "이 메서드들이 공개(Public)인가?라는 질문은 파이썬 객체 모델의 작동 원리를 깊이 이해하는데 중요한 포인트입니다. 이 글에서는 두 메서드의 성격과 파이썬에서의 public, private 개념에 대해 자세히 알아보겠습니다.
주제 개념
파이썬에서 메서드나 속성의 접근 제어는 다른 언어들(JAVA, C++ 등)의 엄격한 public, private 키워드와는 다릅니다. 파이썬은 "We are all consenting adults here" 라는 철학을 바탕으로, 개발자의 약속과 관례를 중시합니다. 이 때문에 공개적으로 사용하도록 의도된 것과 내부적으로만 사용하도록 의도된 것을 이름 규칙으로 구분합니다.
용어 정리
- 공개(public) : 누구나 접근하고 사용할 수 있도록 의도된 멤버
- 비공개(private) : 클래스 내부에서만 사용하도록 의도된 멤버
- 접근 지정자(Access Specifier) : 클래스의 멤버(속성, 메서드)에 대한 접근 권한을 정의하는 키워드(Java의 Public, Private, Protected)
- 네임 맹글링(Name Mangling) : 파이썬에서 __(두개의 언더스코어)로 시작하는 속성 이름을 자동으로 변경하여 외부 접근을 어렵게 만드는 기능
실제 작동 원리 및 예시
파이썬의 던더(dunder) 메서드는 이중 밑줄(__)로 시작하고 끝나는 특별한 메서드 이름입니다. 이 메서드들은 파이썬 내부에서 특정 시점에 자동으로 호출되도록 약속되어 있습니다. __get__ 과 __set__ 역시 이러한 던더(dunder) 메서드에 속합니다.
왜 사용하는지
파이썬은 메서드를 호출할 때 개발자가 직접 obj.__get__(...) 처럼 호출하는 것을 의도하지 않습니다. 대신 obj.attr와 같은 속성 접근 구문을 사용하면, 파이썬 인터프리터가 내부적으로 이 던더 메서드를 호출하여 복잡한 로직을 대신 수행해 줍니다. 이는 사용자에게 직관적인 인터페이스를 제공하면서도 내부적으로는 강력한 제어 기능을 구현할 수 있게 합니다.
언제 사용하는지
디스크립터의 __get__과 __set__은 객체의 속성 값을 읽거나(get) 쓰는(set) 시점에 파이썬에 의해 자동으로 호출됩니다.
어떻게 사용하는지
개발자는 이 던더 메서드를 직접 호출하기보다는 디스크립터 클래스를 만들고 이를 다른 클래스의 속성으로 정의함으로써 파이썬의 속성 접근 프로토콜을 따릅니다.
디스크립터
디스크립터의 __get__과 __set__ 메서드는 형식적으로는 공개(public) 메서드입니다. 파이썬은 언어 차원에서 이들을 private으로 강제하지 않습니다. 즉, 개발자가 마음만 먹으면 descriptor_instance.__get__(...) 처럼 직접 호출할 수 있습니다.
하지만 이 메서드들은 관례적으로는 내부에서 사용되는 메서드로 간주됩니다. 이는 마치 자동차의 엔진에 직접 손을 대기보다는 핸들, 가속 폐달 같은 인터페이스를 사용하는 것과 같습니다. 디스크립터의 던더 메서드들은 파이썬 객체 시스템의 내부 인터페이스 역할을 수행하며, 개발자는 obj.attr = value 와 같은 외부 인터페이스를 통해 이들을 간접적으로 활용합니다.
예시 코드
obj = MyClass()
print(obj.value) # 내부적으로 MyDescriptor.__get__ 호출
# 출력: I am being called automatically by Python's get protocol
# 출력: I am a value
obj.value = 10 # 내부적으로 MyDescriptor.__set__ 호출
# 출력: I am being called automatically by Python's set protocol with value: 10
아래 코드에서 우리는 __get__ 과 __set__을 직접 호출하지 않았음에도 불구하고, 파이썬이 자동으로 이 메서드들을 호출해 주었습니다. 이것이 바로 파이썬의 약속 기반의 공개 인터페이스의 핵심입니다.
class MyDescriptor:
def __get__(self, instance, owner):
# 파이썬이 obj.value를 호출할 때 자동으로 호출
print("I am being called automatically by Python's get protocol")
return "I am a value"
def __set__(self, instance, value):
# 파이썬이 obj.value = 10을 호출할 때 자동으로 호출
print(f"I am being called automatically by Python's set protocol with value: {value}")
class MyClass:
value = MyDescriptor()
장단점 및 특징
장점
- 직관성 : 사용자 입장에서 속성 접근이 매우 자연스럽고 직관적입니다.
- 강력한 제어 : 속성 값을 할당하거나 가져올 때 유효성 검사, 로깅 등 복잡한 로직을 쉽게 추가할 수 있습니다.
단점
- 약한 제약 : __로 시작하는 메서드도 강제적인 접근 제한이 없으므로, 개발자 스스로 규칙을 지켜야 합니다.
특징
- 던더(Dunder) : __get__ , __set__ 과 같은 특별한 이름 규칙을 따릅니다.
- 프로토콜 : 파이썬의 속성 접근 프로토콜의 일부로서, 특정 규칙을 따릅니다.
- 유연성 : 다른 언어의 getter, setter를 대신하는 파이썬 다운 방식입니다.
결론
결론적으로, 파이썬 디스크립터의 __get__ , __set__ 메서드는 기술적으로는 공개(public) 메서드이지만, 파이썬의 객체 모델에서는 특수한 목적으로 사용되는 내부 인터페이스로 간주하는 것이 더 올바른 이해입니다. 파이썬은 개발자에게 자유를 주되, 특정 이름 규칙을 통해 약속된 사용 방식을 제안합니다. 이 약속을 지키는 것이 파이썬의 코딩 철학을 따르는 것이며, 디스크립터의 강력함을 제대로 활용하는 방법입니다.
'Dev > Python' 카테고리의 다른 글
[Python] 동기(Synchronous) & 비동기(Asynchronous) (0) | 2025.09.20 |
---|---|
[Python] 파이썬 디스크립터(Descriptor) (0) | 2025.09.19 |
[Linux] Python 가상환경 생성 과정 정리 (0) | 2025.01.21 |