Skip to main content

Python 描述符 (Descriptors)

大家好!今天我们来聊聊Python的Descriptors。

Descriptors 是一种强大的属性访问控制机制, 主要用于管理和定制属性的访问与修改。通过 实现类型检查、数据验证和延迟计算等功能, 可以实现更加灵活和可控的属性管理。

通过实现 get, set, delete 这三个 方法,你可以精细地控制属性的读取、赋值和删除行为。 例如,Validated descriptor 实现了 类型检查,确保属性值符合预期类型。 LazyLoad descriptor 实现了延迟计算,仅在首次访问属性时 才进行计算,后续访问直接返回缓存结果,从而提高程序性能。

希望这个简单的例子能帮助你理解Python的Descriptors!

代码示例

import time

class Validated:
def __init__(self, type_):
self.type_ = type_
self.value = None

def __get__(self, obj, objtype):
return self.value

def __set__(self, obj, value):
if not isinstance(value, self.type_):
raise TypeError(
f"Expected {self.type_}")
self.value = value

def __delete__(self, obj):
del self.value

class LazyLoad:
def __init__(self, func):
self.func = func
self.value = None

def __get__(self, obj, objtype):
if self.value is None:
print("Calculating...")
start = time.time()
self.value = self.func(obj)
end = time.time()
print(f"Done in {end - start:.2f}s")
return self.value

def __set__(self, obj, value):
raise AttributeError(
"Cannot set lazy loaded attribute")

def __delete__(self, obj):
self.value = None

class MyClass:
age = Validated(int)
name = Validated(str)
expensive_value = LazyLoad(
lambda self: sum(range(1000)))

instance = MyClass()
instance.age = 30
instance.name = "Alice"
print(instance.age)
print(instance.name)
print(instance.expensive_value)
print(instance.expensive_value)

del instance.age