看登录中间件的时候发现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的更多相关文章

  1. PDF在线阅读 FlexPaper 惰性加载 ;

    关于PDF在线阅读问题,比较普遍的做法是转换成swf文件来浏览:由于项目需要,就用 flexpaper 来实现了下,功能比较简单:但是文件的惰性加载确实让笔者挠头了一把! 下面是笔者的方法: 采用流的 ...

  2. Angular2 ng2 如何配置惰性加载

    需要修改至少四个地方1. 将子组件进行模块化操作2.生成子组件module .子组件router3.配置主路由 信息 改为loadChild4.配置appModule 删除引入 以product组件 ...

  3. 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格惰性加载节点

    jQuery EasyUI 树形菜单 - 树形网格惰性加载节点 有时我们已经得到充分的分层树形网格(TreeGrid)的数据. 我们还想让树形网格(TreeGrid)按层次惰性加载节点. 首先,只加载 ...

  4. angular惰性加载拓展剖析

    最近把一个比较旧的业余项目重新升级了下,将主文件进行了剥离,增加了些惰性加载的配置,将过程中一些零散的知识点做个总结,同时尽量深入原理实现层面. 项目环境: 前端框架:angular2.0.0-bet ...

  5. 关于angular5的惰性加载报错问题

    之前为了测试一个模块优化问题,于是用angular-cli快速搭建了个ng5的脚手架demo,在应用惰性加载功能的时候发现浏览器报错如下: ERROR Error: Uncaught (in prom ...

  6. Angular惰性加载的特性模块

    一:Angular-CLI建立应用 cmd命令:ng new lazy-app --routing    (创建一个名叫 lazy-app 的应用,而 --routing 标识生成了一个名叫 app- ...

  7. django如何加载外部文件

    django如何加载外部文件(环境:pycharm python2.7 django1.11) 有一份新的文件夹名为:py_aiplat_demo,内含有多个文件夹(SDK,demo,data). 1 ...

  8. javascript 性能惰性加载2016.12.13

    利用函数的惰性载入提高 javascript 代码性能 原文:利用函数的惰性载入提高javascript代码性能 作者:阿安 在 javascript 代码中,因为各浏览器之间的行为的差异,我们经常会 ...

  9. django无法加载admin的静态内容的问题(Centos7+Nginx+uwsgi环境下)

    Nginx静态资源无法加载,导致admin没有CSS样式: 这个问题,主要是要理解: 1.Django不会去解析静态内容(css,js,img)等,而是交给Nginx去处理,所以nginx.conf要 ...

随机推荐

  1. 「题解」:$e$

    问题 B: $e$ 时间限制: 2 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 话说一天考两个主席树这回事…… 正解可以叫树上主席树??(脸哥说也叫主席树上树???) 对于树上的每 ...

  2. C++——虚析构

    目的: //只执行了 父类的析构函数//向通过父类指针 把 所有的子类对象的析构函数 都执行一遍//向通过父类指针 释放所有的子类资源 方法:在父类的析构函数前+virtual关键字 #define ...

  3. MFC基础类及其层次结构

    从类CCmdTarget派生出绝大多数MFC中的类,其层次结构如下图: 从根类Cobject层层派生出绝大多数MFC中的类,层次结构如下图: MFC中重点类: CObject类是MFC的绝大部分类的基 ...

  4. Windows的DOS命令

    f:    d:                                                                                            ...

  5. Django框架中session存储到redis中的配置

    本文链接:https://blog.csdn.net/linqunbin/article/details/94786313————————————————版权声明:本文为CSDN博主「linqunbi ...

  6. 使用Math.random()函数生成n到m间的随机数字

    使用js生成n到m间的随机数字,主要目的是为后期的js生成验证码做准备,Math.random()函数返回0和1之间的伪随机数 讲解: 本文讲解如何使用js生成n到m间的随机数字,主要目的是为后期的j ...

  7. mvc中在cshtml页面中如何访问静态页面.html

    把静态页面放到@Url.Content();中,如href="@Url.Content("a.html")"

  8. html--垂直居中

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  9. nicescroll 使用与配置

    使用// 1. 简单模式,设置html元素滚动 $(document).ready(function() { $("html").niceScroll(); }); // 2. 返 ...

  10. UNION操作用于合并两个或多个 SELECT 语句的结果集。

    UNION操作用于合并两个或多个 SELECT 语句的结果集. 大理石平台价格 使用示例: $Model->field('name') ->table('think_user_0') -& ...