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