파이썬에서 객체의 속성에 접근하는 방법에는 여러 가지가 있다.
다섯 가지 주요 방법에 대해 설명하고, 각 방법의 장단점과 사용 사례를 소개하려고한다.
가장 간단한 방법으로, 객체의 속성에 직접 접근
class MyAge:
def __init__(self, age):
self._age = age
obj = MyAge(20)
print(obj._age) # 출력: 20
obj._age = 30
print(obj._age) # 출력: 30
getter와 setter 메서드를 직접 구현하여 속성 접근을 제어하는 방법
class MyAge:
def __init__(self, age):
self._age = age
def get_age(self):
return self._age
def set_age(self, age):
if age < 0:
raise ValueError("나이는 0보다 작을 수 없음")
self._age = age
obj = MyAge(20)
print(obj.get_age()) # 출력: 20
obj.set_age(30)
print(obj.get_age()) # 출력: 30
@property 데코레이터를 사용하여 속성 접근을 메서드로 처리하되, 속성처럼 보이게 하는 방법
class MyAge:
def __init__(self, age):
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if age < 0:
raise ValueError("나이는 0보다 작을 수 없음")
self._age = age
obj = MyAge(20)
print(obj.age) # 출력: 20
obj.age = 30
print(obj.age) # 출력: 30
# obj.age = -5 # ValueError: 나이는 0보다 작을 수 없음
디스크립터 클래스를 정의하고 이를 통해 속성 접근을 제어하는 방법
from weakref import WeakKeyDictionary
class Descriptor:
def __init__(self):
self.data = WeakKeyDictionary()
def __get__(self, instance, instance_type):
if instance is None:
return self
return self.data.get(instance, 0)
def __set__(self, instance, value):
if value < 0:
raise ValueError(f"{self.name}는 0보다 작을 수 없음")
self.data[instance] = value
class MyAge:
age = Descriptor()
height = Descriptor()
def __init__(self, age, height):
self.age = age
self.height = height
- Descriptor 클래스는 __get__, __set__ 모두 구현하였으므로 디스크립터로 판단된다.
- WeakKeyDictionary 사용이유 : 각각의 유일한 MyAge 인스턴스가 Descriptor 클래스를 공유하지 않으면서 메모리 누수를 막기위함 (일반 딕셔너리에서 강한 참조 X 약한 참조 O)
__getattr__, __getattribute__, __setattr__ 사용이 메서드들을 사용하여 속성 접근을 세밀하게 제어할 수 있습니다.
class MyAge:
def __init__(self, age):
self._age = age
def __getattr__(self, name):
return f"{name} 속성은 존재하지 않습니다.
"
def __getattribute__(self, name):
print(f"{name} 속성에 접근 중 __getattribute__ 호출됨
")
return super().__getattribute__(name)
def __setattr__(self, name, value):
print(f"{name} 속성에 {value} 값을 설정 중
")
self.__dict__[name] = value
obj = MyAge(10) # _age 속성에 10 값을 설정 중
obj.age = 40 # age 속성에 40 값을 설정 중
print(obj.age) # age 속성에 접근 중 __getattribute__ 호출됨
40
print(obj.non_existent_attr) # non_existent_attr 속성에 접근 중 __getattribute__ 호출됨
non_existent_attr 속성은 존재하지 않습니다.
이 다섯 가지 방법을 통해 파이썬에서 객체의 속성 접근을 다양하게 제어할 수 있습니다.
각 방법의 장단점과 사용 사례를 잘 이해하면, 적절한 상황에 맞는 접근 방식을 선택할 수 있을 것입니다.