django源码分析 LazySetting对象
2019-04-11 10:49:19来源:博客园 阅读 ()
一、django中通过LazySetting对象来获取项目的配置,LazySetting对象有什么特性?为什么使用这个对象?
LazySetting顾名思义,就是延迟获取配置内容。比如,我们定义了一个对象A,并对其添加了一些属性,对A初始化时,我们将A的属性的值设置为空,当我们要访问A其中的一个属性时,此时属性的值为空,我们才加载属性的值,并将空值设置为对应的值,返回属性值,下次获取属性值时,属性值不为空,直接返回属性值。
为什么要使用LazySetting?
django项目在初始化的时候, 通过LazySetting,我们就可以在django获取某个配置的值之前,将配置的值先自定义为某个值,django再去获取该配置的值的时候,配置已经有了值,直接返回该配置的值。
二、django是如何实现LazySetting对象的?
1. 在说LazySetting对象之前,我们先看一下python的类属性的查找方式:
在查找一个实例化的类属性的时候
- 首先查找这个类的实例属性是否存在,存在直接返回
- 如果类的实例属性中不存在,则在类的类属性中查找,类属性中存在,则返回
- 如果类属性中也不存在,若定义了__getattr__方法,则根据__getattr__方法获取属性
在python中类属性和实例属性会记录在类的一个内置变量__dict__中,类属性和实例属性有各自维护的__dict__
class A: a = '类属性' def __init__(self): self.a = '实例属性' print(A.__dict__) print(A().__dict__)
输出的结果为
{'__module__': '__main__', 'a': '类属性', '__init__': <function A.__init__ at 0x04BBAB28>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None} {'a': '实例属性'}
注意的是,类属性里面不只有a属性,还有一些其他类有关的属性
我们可以看到,类属性里面a的值和实例属性里面a的值不一样。类属性和实例属性是分别维护的。
2. 下面我们写几个实例化的类查找属性的例子
第一个例子
class A: a = 'Aa' b = 'Bb' def __init__(self): self.a = 'aa' obj = A() print(obj.a) print(obj.b)
输出的结果是(先在实例属性中查找,找不到,再到类属性中查找)
aa
Bb
如果我们print(obj.c)则会报错,因为在类属性中和实例属性中都找不到c
第二个例子
class A: a = 'Aa' b = 'Bb' def __init__(self): self.a = 'aa' def __getattr__(self, item): return 'cc' obj = A() print(obj.a) print(obj.b) print(obj.c)
输出的结果和上面类似,只是print(obj.c)不报错了,因为我们定义了__getattr__方法,实例属性中和类属性中都找不到时,就会使用这个方法获取属性
aa
Bb
cc
3. django的LazySetting类的实现
LazySetting类的实现就是通过定义__getattr__方法实现的,LazySetting类的__getattr__源码如下
def __getattr__(self, name): """Return the value of a setting and cache it in self.__dict__.""" if self._wrapped is empty: self._setup(name) val = getattr(self._wrapped, name) self.__dict__[name] = val return val
我们在LazySetting对象中查找一个属性的时候,先在实例属性(self.__dict__)中查找,没有找到话,通过__getattr__方式获取,获取到后,将属性值保存到实例属性中,这样就实现了属性在使用的时候
再获取,然后保存。我们还可以再获取属性之前,先将属性的值自定义,这样就可以不用使用__getattr__的方式来获取默认的值。
三、总结
延迟加载的方式,可以在编程中优化我们类的初始化动作,比如,我们创建了一个类有很多属性,这些属性的值都需要通过计算的方式获取,我们在初始化的时候,就要把属性的值计算出来,这些计算出来属性,我们后面有可能能会用不到,这样的话,类的初始化就计算属性的值方式会浪费大量的计算机资源;使用延迟加载的方式,就可以很好的解决这种问题,到使用属性值的时候再获取。
原文链接:https://www.cnblogs.com/time-read/p/10580378.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:python运算符优先级表
下一篇:罗马数字与阿拉伯数字转换
- Django项目中使用qq第三方登录。 2019-08-13
- python多线程同步实例分析 2019-08-13
- Django和前端用ajax传输json等数据 2019-08-13
- Django基本知识 2019-08-13
- JavaScript获取Django模板中指定键值的数据,使用过滤器 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash