写点什么

python 实现类属性的懒加载装饰器

用户头像
一代咩神
关注
发布于: 2021 年 04 月 15 日
class lazy:    # 告诉 Python 不要创建对象的 __dict__,而是只给一个固定集合的属性分配空间。    __slots__ = ['func']
def __init__(self, func): self.func = func
def __get__(self, instance, owner): name = self.func.__name__ # 如果 func 不为 None 则赋值给 owner (这里是 `MyClass`) 的 `name` 属性, # 此后 owner 的 name() 不再是装饰器方法,而是实实在在的 func() 方法返回值! if (v := self.func(owner)) is not None: setattr(owner, name, v) return owner.__dict__.get(name) if v else None
class MyClass: @lazy def name(self) -> str: print("debug: name(self)") return "get name"
if __name__ == '__main__': name = MyClass.name # output: 'debug: name(self)' print(f'[{name}]', type(name)) # => [get name] <class 'str'> print(f'[{MyClass.name}]') # => [get name]
复制代码


第一次调用 MyClass.name 时会进入到装饰器的 __get__ 方法中返回值,我们在 __get__ 方法的内部再重新把装饰器的 func 返回值赋值给 owner ( 这里是 MyClass ) 的 name 属性,从而达到 替换值 的概念。

用户头像

一代咩神

关注

还未添加个人签名 2019.04.18 加入

还未添加个人简介

评论

发布
暂无评论
python 实现类属性的懒加载装饰器