Django惰性加载和LazyObject
看登录中间件的时候发现request.user返回的是SimpleOject对象,往下看翻到了LazyObject,看源码看了半天没看懂
网上搜了一堆资料了解下惰性加载实现是的什么功能,再回去看源码,大概知道了LazyObject实现的原理
Django的惰性加载,就是生成对象的时候先不实例化,等到需要调用对象的属性或方法的时候再做实例化的操作
LazyObject源码:
empty = object() #为类方法实现通用的惰性加载方法,即查看对象是否实例化
#若还未实例化,调用子类实例化方法
#最后在生成的实例上调用原来的func类方法
def new_method_proxy(func):
def inner(self, *args):
if self._wrapped is empty:
self._setup()
return func(self._wrapped, *args)
return inner class LazyObject:
"""
A wrapper for another class that can be used to delay instantiation of the
wrapped class. By subclassing, you have the opportunity to intercept and alter the
instantiation. If you don't need to do that, use SimpleLazyObject.
""" # Avoid infinite recursion when tracing __init__ (#19456).
_wrapped = None def __init__(self):
# Note: if a subclass overrides __init__(), it will likely need to
# override __copy__() and __deepcopy__() as well.
self._wrapped = empty #标记是否有实例化 __getattr__ = new_method_proxy(getattr) #调用通用的延迟实例化方法 def __setattr__(self, name, value):
if name == "_wrapped": #若修改的为_wrapped,特殊处理
# Assign to __dict__ to avoid infinite __setattr__ loops.
self.__dict__["_wrapped"] = value
else:
if self._wrapped is empty:
self._setup()
setattr(self._wrapped, name, value) #实例化后,修改实例的属性 def __delattr__(self, name):
if name == "_wrapped": #不可删除_wrapped属性
raise TypeError("can't delete _wrapped.")
if self._wrapped is empty:
self._setup()
delattr(self._wrapped, name) def _setup(self):
"""
Must be implemented by subclasses to initialize the wrapped object.
"""
#只可由子类调用
raise NotImplementedError('subclasses of LazyObject must provide a _setup() method') # Because we have messed with __class__ below, we confuse pickle as to what
# class we are pickling. We're going to have to initialize the wrapped
# object to successfully pickle it, so we might as well just pickle the
# wrapped object since they're supposed to act the same way.
#
# Unfortunately, if we try to simply act like the wrapped object, the ruse
# will break down when pickle gets our id(). Thus we end up with pickle
# thinking, in effect, that we are a distinct object from the wrapped
# object, but with the same __dict__. This can cause problems (see #25389).
#
# So instead, we define our own __reduce__ method and custom unpickler. We
# pickle the wrapped object as the unpickler's argument, so that pickle
# will pickle it normally, and then the unpickler simply returns its
# argument.
def __reduce__(self):
if self._wrapped is empty:
self._setup()
return (unpickle_lazyobject, (self._wrapped,)) def __copy__(self):
if self._wrapped is empty:
# If uninitialized, copy the wrapper. Use type(self), not
# self.__class__, because the latter is proxied.
return type(self)()
else:
# If initialized, return a copy of the wrapped object.
return copy.copy(self._wrapped) def __deepcopy__(self, memo):
if self._wrapped is empty:
# We have to use type(self), not self.__class__, because the
# latter is proxied.
result = type(self)()
memo[id(self)] = result
return result
return copy.deepcopy(self._wrapped, memo) __bytes__ = new_method_proxy(bytes)
__str__ = new_method_proxy(str)
__bool__ = new_method_proxy(bool) # Introspection support
__dir__ = new_method_proxy(dir) # Need to pretend to be the wrapped class, for the sake of objects that
# care about this (especially in equality tests)
__class__ = property(new_method_proxy(operator.attrgetter("__class__")))
__eq__ = new_method_proxy(operator.eq)
__lt__ = new_method_proxy(operator.lt)
__gt__ = new_method_proxy(operator.gt)
__ne__ = new_method_proxy(operator.ne)
__hash__ = new_method_proxy(hash) # List/Tuple/Dictionary methods support
__getitem__ = new_method_proxy(operator.getitem)
__setitem__ = new_method_proxy(operator.setitem)
__delitem__ = new_method_proxy(operator.delitem)
__iter__ = new_method_proxy(iter)
__len__ = new_method_proxy(len)
__contains__ = new_method_proxy(operator.contains)
Django惰性加载和LazyObject的更多相关文章
- PDF在线阅读 FlexPaper 惰性加载 ;
关于PDF在线阅读问题,比较普遍的做法是转换成swf文件来浏览:由于项目需要,就用 flexpaper 来实现了下,功能比较简单:但是文件的惰性加载确实让笔者挠头了一把! 下面是笔者的方法: 采用流的 ...
- Angular2 ng2 如何配置惰性加载
需要修改至少四个地方1. 将子组件进行模块化操作2.生成子组件module .子组件router3.配置主路由 信息 改为loadChild4.配置appModule 删除引入 以product组件 ...
- 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格惰性加载节点
jQuery EasyUI 树形菜单 - 树形网格惰性加载节点 有时我们已经得到充分的分层树形网格(TreeGrid)的数据. 我们还想让树形网格(TreeGrid)按层次惰性加载节点. 首先,只加载 ...
- angular惰性加载拓展剖析
最近把一个比较旧的业余项目重新升级了下,将主文件进行了剥离,增加了些惰性加载的配置,将过程中一些零散的知识点做个总结,同时尽量深入原理实现层面. 项目环境: 前端框架:angular2.0.0-bet ...
- 关于angular5的惰性加载报错问题
之前为了测试一个模块优化问题,于是用angular-cli快速搭建了个ng5的脚手架demo,在应用惰性加载功能的时候发现浏览器报错如下: ERROR Error: Uncaught (in prom ...
- Angular惰性加载的特性模块
一:Angular-CLI建立应用 cmd命令:ng new lazy-app --routing (创建一个名叫 lazy-app 的应用,而 --routing 标识生成了一个名叫 app- ...
- django如何加载外部文件
django如何加载外部文件(环境:pycharm python2.7 django1.11) 有一份新的文件夹名为:py_aiplat_demo,内含有多个文件夹(SDK,demo,data). 1 ...
- javascript 性能惰性加载2016.12.13
利用函数的惰性载入提高 javascript 代码性能 原文:利用函数的惰性载入提高javascript代码性能 作者:阿安 在 javascript 代码中,因为各浏览器之间的行为的差异,我们经常会 ...
- django无法加载admin的静态内容的问题(Centos7+Nginx+uwsgi环境下)
Nginx静态资源无法加载,导致admin没有CSS样式: 这个问题,主要是要理解: 1.Django不会去解析静态内容(css,js,img)等,而是交给Nginx去处理,所以nginx.conf要 ...
随机推荐
- 【Servlet】Servlet监听器
一.Servlet监听器的概念 Servlet监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext.HttpSession和ServletRequest等域对象的创建与销 ...
- 共享商业&技术红利,阿里云SaaS加速器让天下没有难做的SaaS
9月26日,阿里云在2019杭州云栖大会上发布了SaaS加速器3.0版“一云多端”多个应用平台,展示了阿里云给伙伴带来的多种商业和技术红利.阿里云SaaS加速器将帮助伙伴做好SaaS,卖好SaaS:帮 ...
- http://wiki.ros.org/navigation/Tutorials/RobotSetup
http://wiki.ros.org/navigation/Tutorials/RobotSetup
- duilib教程之duilib入门简明教程6.XML配置界面
前面那些教程都是为了让小伙伴们从win32.MFC过渡到duilib,让大家觉得duilib不是那么陌生,如果大家现在还对duilib非常陌生的话,那就说明前面的教程做得不好,请大家在下面留言,我会一 ...
- VS2010-MFC(状态栏的使用详解)
转自:http://www.jizhuomi.com/software/219.html 上一节讲了工具栏的创建.停靠与使用,本节来讲解状态栏的知识. 状态栏简介 状态栏相信大家在很多窗口中都能见到, ...
- STM32之glossary
glossary Word: data/instruction of 32-bit length. Half word: data/instruction of 16-bit length. Byte ...
- let能否完全替代IIFE
let是什么 http://es6.ruanyifeng.com/#docs/let 最近,我写了一篇关于syntax of Java’s IIFE pattern的文章,来解释为什么我们用现在的方式 ...
- QT之QByteArray
1.拷贝内容到QByteArray 1.使用append函数 //结合结构体的(char*)强制转化使用,command.append((char*)&e2_System_Para_t, si ...
- docker上安装ActiveMQ
1.查看是否已经存在镜像 docker images 2.搜索镜像 docker search activemq 3.拉取镜像 docker pull webcenter/activemq 4.构建容 ...
- 2019-9-23-asp-dotnet-core-3.0-接口返回-json-使用-PascalCase-格式
title author date CreateTime categories asp dotnet core 3.0 接口返回 json 使用 PascalCase 格式 lindexi 2019- ...