Python 对象的延迟初始化是指,当它第一次被创建时才进行初始化,或者保存第一次创建的结果,然后每次调用的时候直接返回该结果。

延迟初始化主要用于提高性能,避免浪费计算,并减少程序的内存需求。

property

在切入正题之前,我们了解下property的用法,property可以将属性的访问转变成方法的调用。

class Circle(object): def __init__(self, radius): self.radius = radius @propertydef area(self): return 3.14 * self.radius ** 2c = Circle(4)
print c.radius
print c.area 

可以看到,area虽然是定义成一个方法的形式,但是加上@property后,可以直接执行c.area,当成属性访问。

现在问题来了,每次调用c.area,都会计算一次,太浪费cpu了,怎样才能只计算一次呢?这就是lazy property

lazy property

实现延迟初始化有两种方式,一种是使用python描述符,另一种是使用@property修饰符。

方式1:

class lazy(object): def __init__(self, func): self.func = func def __get__(self, instance, cls): val = self.func(instance) setattr(instance, self.func.__name__, val) return val class Circle(object): def __init__(self, radius): self.radius = radius @lazydef area(self): print 'evalute'return 3.14 * self.radius ** 2c = Circle(4)
print c.radius
print c.area
print c.area
print c.area 

结果'evalute'只输出了一次。在lazy类中,我们定义了__get__()方法,所以它是一个描述符。当我们第一次执行c.area时,python解释器会先从c.__dict__中进行查找,没有找到,就从Circle.__dict__中进行查找,这时因为area被定义为描述符,所以调用__get__方法。

__get__()方法中,调用实例的area()方法计算出结果,并动态给实例添加一个同名属性area,然后将计算出的值赋予给它,相当于设置c.__dict__['area']=val

当我们再次调用c.area时,直接从c.__dict__中进行查找,这时就会直接返回之前计算好的值了。

不太懂python描述符的话,可以参考Descriptor HowTo Guide。

方式2

def lazy_property(func):attr_name = "_lazy_" + func.__name__@propertydef _lazy_property(self):if not hasattr(self, attr_name):setattr(self, attr_name, func(self))return getattr(self, attr_name)return _lazy_propertyclass Circle(object): def __init__(self, radius): self.radius = radius @lazy_propertydef area(self): print 'evalute'return 3.14 * self.radius ** 2

这里与方法1异曲同工,在area()前添加@lazy_property相当于运行以下代码:

lazy_property(area)

lazy_property()方法返回_lazy_property_lazy_property又会调用_lazy_property()方法,剩下的操作与方法1类似。

我们可以检查下是否真的延迟初始化了:

c = Circle(4)
print "before first visit"
print c.__dict__
c.area
print "after first visit"
print c.__dict__

输出结果为:

before first visit
{'radius': 4}
evalute
after first visit
{'_lazy_area': 50.24, 'radius': 4}

从中可以看书,只有当我们第一次访问c.area时,才调用area方法,说明确实延迟初始化了。

参考文献

  • Descriptor HowTo Guide

  • lazy evaluation

  • python中的property及实现lazy property(原博客已找不到)

Python 延迟初始化(lazy property)相关推荐

  1. Scala中的延迟初始化(Lazy vals)

    延迟初始化(Lazy vals) 除了前面介绍的预先初始化成员值外,你还是让系统自行决定何时初始化成员的初始值,这是通过在 val 定义前面添加 lazy(懒惰),也是说直到你第一次需要引用该成员是, ...

  2. 利用Python延迟初始化提升性能

    所谓类属性的延迟计算就是将类的属性定义成一个property,只在访问的时候才会计算,而且一旦被访问后,结果将会被缓存起来,不用每次都计算.构造一个延迟计算属性的主要目的是为了提升性能 propert ...

  3. 【CSharp】延迟初始化(Lazy)

    参考 https://www.jb51.net/article/202143.htm 1. 什么是延迟初始化 延迟初始化是一种将对象的创建延迟到第一次需要用时的技术,换句话说,对象的初始化是发生在真正 ...

  4. Kotlin实战指南九:延迟初始化

    转载请标明出处:https://blog.csdn.net/zhaoyanjun6/article/details/93764289 本文出自[赵彦军的博客] 高阶函数 lateinit 延迟初始化 ...

  5. java 延迟初始化_Java - 延迟初始化

    延迟初始化(lazy initialization),也就是在真正被使用的时候才开始初始化的技巧. 不论是静态还是实例,都可以进行延迟初始化. 其本质是初始化开销和访问开销之间的权衡. 毕竟是一种优化 ...

  6. python基础教程:懒惰属性(延迟初始化)

    Python 对象的延迟初始化是指,当它第一次被创建时才进行初始化,或者保存第一次创建的结果,然后每次调用的时候直接返回该结果.延迟初始化主要用于提高性能,避免浪费计算,并减少程序的内存需求. 1. ...

  7. python中area是什么意思_python之懒惰属性(延迟初始化)

    原标题:python之懒惰属性(延迟初始化) Python 对象的延迟初始化是指,当它第一次被创建时才进行初始化,或者保存第一次创建的结果,然后每次调用的时候直接返回该结果.延迟初始化主要用于提高性能 ...

  8. C#编程,Lazy(延迟初始化)用法

    1. 简介 从net 4.0开始,C#开始支持延迟初始化,通过Lazy关键字,我们可以声明某个对象为仅仅当第一次使用的时候,再初始化,如果一直没有调用,那就不初始化,省去了一部分不必要的开销,提升了效 ...

  9. C#技巧 Lazy(延迟初始化)用法

    1. 简介 从net 4.0开始,C#开始支持延迟初始化,通过Lazy关键字,我们可以声明某个对象为仅仅当第一次使用的时候,再初始化,如果一直没有调用,那就不初始化,省去了一部分不必要的开销,提升了效 ...

最新文章

  1. 红旗Linux认证简介
  2. linux拒绝sftp连接,linux服务器拒绝sftp
  3. 如何使用python爬取百度图片_python实现爬取百度图片的方法示例
  4. 解决客户端从服务器请求数据乱码问题
  5. DEBUG_NEW和THIS_FILE
  6. Php错误邮件提示linux,linux下phpmailer发送邮件出现SMTP ERROR: Failed to connect to server: (0)错误...
  7. abs函数的使用方法 oracle_SQL Server 常用函数使用方法
  8. 1003 Express Mail Taking
  9. iOS 九宫格手势密码
  10. 再谈网络字节顺序,大小端问题
  11. 教你一招用 Python Turtle 库画出“精美碎花小清新风格树”,速取代码! | 原力计划...
  12. php源码 学校版 cms,S-CMS学校建站系统PHP源码(含小程序) v5.0 bulid20201126
  13. 【Linux从青铜到王者】第二十四篇:Linux网络基础第四篇之WebSocket协议
  14. 算法设计之动态规划法
  15. BOSS创投社群:要想成为富人,得改变原有思维,谈谈什么是富人思维模式!
  16. 什么是AJAX四步?分别是?(AJAX的使用)
  17. 用 TableModel Free 框架简化 Swing 开发——JTable
  18. 搭建网络流量监控cacti
  19. 【转】100种消灭无聊的方法,很有爱,看到第100个,我笑喷了
  20. JAVA开发运维(扁鹊见齐桓公之系统运维之痛)

热门文章

  1. Linux下Apache并发连接数和带宽控制
  2. Python高级特性:切片
  3. 使用OpenApi弹性管理云服务器ECS
  4. asp.net url重写相关技术问题整理
  5. SPOJ 130 - Rent your airplane and make money(dp+优化)
  6. Linux命令之whereis
  7. 中国小孩为何普遍爱吃洋快餐?[转]
  8. android LayoutInflater.inflate()的参数及其用法
  9. django 快速实现注册
  10. 实现DFS之“油田”