django源码分析 LazySetting对象
一、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__的方式来获取默认的值。
三、总结
延迟加载的方式,可以在编程中优化我们类的初始化动作,比如,我们创建了一个类有很多属性,这些属性的值都需要通过计算的方式获取,我们在初始化的时候,就要把属性的值计算出来,这些计算出来属性,我们后面有可能能会用不到,这样的话,类的初始化就计算属性的值方式会浪费大量的计算机资源;使用延迟加载的方式,就可以很好的解决这种问题,到使用属性值的时候再获取。
django源码分析 LazySetting对象的更多相关文章
- netty源码分析 - Recycler 对象池的设计
目录 一.为什么需要对象池 二.使用姿势 2.1 同线程创建回收对象 2.2 异线程创建回收对象 三.数据结构 3.1 物理数据结构图 3.2 逻辑数据结构图(重要) 四.源码分析 4.2.同线程获取 ...
- Django源码分析之启动wsgi发生的事
前言 好多人对技术的理解都停留在懂得使用即可,因而只会用而不会灵活用,俗话说好奇害死猫,不然我也不会在凌晨1.48的时候决定写这篇博客,好吧不啰嗦了 继续上一篇文章,后我有个问题(上文:&qu ...
- 2、Django源码分析之启动wsgi发生了哪些事
一 前言 Django是如何通过网络socket层接收数据并将请求转发给Django的urls层? 有的人张口就来:就是通过wsgi(Web Server Gateway Interface)啊! D ...
- django源码分析 python manage.py runserver
django是一个快速开发web应用的框架, 笔者也在django框架上开发不少web应用,闲来无事,就想探究一下django底层到底是如何实现的,本文记录了笔者对django源码的分析过程 I be ...
- django源码分析——本地runserver分析
本文环境python3.5.2,django1.10.x系列 1.根据上一篇文章分析了,django-admin startproject与startapp的分析流程后,根据django的官方实例此时 ...
- django源码分析
原文网址 https://www.jianshu.com/p/17d78b52c732?utm_campaign=maleskine&utm_content=note&utm_medi ...
- django源码分析——处理请求到wsgi及视图view
本文环境python3.5.2,django1.10.x系列 根据前上一篇runserver的博文,已经分析了本地调试服务器的大致流程,现在我们来分析一下当runserver运行起来后,django框 ...
- jQuery 2.0.3 源码分析 回调对象 - Callbacks
源码API:http://api.jquery.com/jQuery.Callbacks/ jQuery.Callbacks()是在版本1.7中新加入的.它是一个多用途的回调函数列表对象,提供了一种强 ...
- django源码分析——静态文件staticfiles中间件
本文环境python3.5.2,django1.10.x系列 1.在上一篇文章中已经分析过handler的处理过程,其中load_middleware就是将配置的中间件进行初始化,然后调用相应的设置方 ...
随机推荐
- Kubernetes 笔记 07 豌豆荚之旅(二)
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Hi,大家好, ...
- Heacher互助平台需求分析
课程属性 作业课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 作业链接 https://edu.cnblogs.co ...
- Python内置函数(5)——bin
英文文档: bin(x) Convert an integer number to a binary string. The result is a valid Python expression. ...
- Java中的String,StringBuilder,StringBuffer三者的区别(转载)
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...
- api-ms-win-crt-process-l1-1-0.dll 丢失的处理,遇到问题和完美解决
api-ms-win-crt-process-l1-1-0.dll 丢失的处理 简介 在换了新电脑后,一些环境需要重新搭建,本以为是个小case,没想到竟然遇到了各种拦路虎. 在成功安装Python3 ...
- RabbitMQ学习笔记(五) Topic
更多的问题 Direct Exchange帮助我们解决了分类发布与订阅消息的问题,但是Direct Exchange的问题是,它所使用的routingKey是一个简单字符串,这决定了它只能按照一个条件 ...
- 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)
接触过线程安全的同学想必都使用过synchronized这个关键字,在java同步代码快中,synchronized的使用方式无非有两个: 通过对一个对象进行加锁来实现同步,如下面代码. synchr ...
- 微服务SpringCloud容器化案例
前言 当我们在使用微服务的时候,那么有一个问题一定会困扰我们,那就是项目的测试和部署.因为在单体应用下,部署项目很简单,直接打包启动就可以了,而对于微服务来说,因为有各个组件的存在所以让测试和部署都变 ...
- Chapter 5 Blood Type——6
"Yes — giving up trying to be good. I'm just going to do what I want now, and let the chips fal ...
- Chapter 5 Blood Type——3
Disappointment flooded through me as my eyes unerringly focused on his table. 当我的眼睛完全集中在他的桌上时,失望如洪水般 ...