Introduction
Descriptors provide a way to customize attribute access with getter, setter, and deleter methods.
Data Descriptor
class Descriptor:
def __get__(self, obj, objtype=None):
print(f"Getting: {obj}")
return obj.__dict__.get('_value', 0)
def __set__(self, obj, value):
print(f"Setting: {value}")
obj.__dict__['_value'] = value
def __delete__(self, obj):
print("Deleting")
del obj.__dict__['_value']
class MyClass:
attribute = Descriptor()
Property as Descriptor
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def diameter(self):
return self.radius * 2
@diameter.setter
def diameter(self, value):
self.radius = value / 2
Function vs Method
class MyClass:
def method(self):
pass # Function becomes bound method
# Bound method
obj = MyClass()
print(obj.method) # <bound method MyClass.method of <MyClass>>
Practice Problems
- Create descriptor with validation
- Implement lazy loading descriptor
- Create read-only descriptor
- Build computed property descriptor
- Use descriptor for unit conversion