好代码系列(一):LazyObject

site-packages/django/utils/functional.py
 1 def new_method_proxy(func):
 2     def inner(self, *args):
 3         if self_wrapped is empty:
 4             self._setup()
 5         return func(self._wrapped, *args)
 6     return inner
 7
 8 class LazyObject(object):
 9     """
10     A wrapper for another class that can be used to delay instantiation of the wrapped class.
11
12     By subclassing, you have the opportunity to intercept and alter the
13 instantiation. If you don‘t need to do that, use SimpleLazyObject.
14     """
15
16     # Avoid infinite recursion when tracing __init__ (#19456).
17     _wrapped = None
18
19     def __init__(self):
20         self._wrapped = empty
21
22     __getattr__ = new_method_proxy(getattr)
23
24     def __setattr__(self, name, value):
25         if name == "_wrapped":
26             # Assign to __dict__ to avoid infinite __setattr__ loops.
27             self.__dict__["_wrapped"] = value
28         else:
29             if self._wrapped is empty:
30                 self._setup()
31             setattr(self._wrapped, name, value)
32
33     def __delattr__(self, name):
34         if name == "_wrapped":
35             raise TypeError("can‘t delete _wrapped.")
36         if self._wrapped is empty:
37             self._setup()
38         delattr(self._wrapped, name)
39
40     def _setup(self):
41         """
42         Must be implemented by subclasses to initialize the wrapped object.
43         """
44         raise NotImplementedError(‘subclasses of LazyObject must provide a _setup() method‘)
45
46     # Because we have messed with __class__ below, we confuse pickle as to what
47     # class we are pickling. We‘re going to have to initialize the wrapped
48     # object to successfully pickle it, so we might as well just pickle the
49     # wrapped object since they‘re supposed to act the same way.
50     #
51     # Unfortunately, if we try to simply act like the wrapped object, the ruse
52     # will break down when pickle gets our id(). Thus we end up with pickle
53     # thinking, in effect, that we are a distinct object from the wrapped
54     # object, but with the same __dict__. This can cause problems (see #25389).
55     #
56     # So instead, we define our own __reduce__ method and custom unpickler. We
57     # pickle the wrapped object as the unpickler‘s argument, so that pickle
58     # will pickle it normally, and then the unpickler simply returns its
59     # argument.
60     def __reduce__(self):
61         if self._wrapped is empty:
62             self._setup()
63         return (unpickle_lazyobject, (self._wrapped,))
64
65     # We have to explicitly override __getstate__ so that older versions of
66     # pickle don‘t try to pickle the __dict__ (which in the case of a
67     # SimpleLazyObject may contain a lambda). The value will end up being
68     # ignored by our __reduce__ and custom unpickler.
69     def __getstate__(self):
70         return {}
71
72     def __deepcopy__(self, memo):
73         if self._wrapped is empty:
74             # We have to use type(self), not self.__class__, because the
75             # latter is proxied.
76             result = type(self)()
77             memo[id(self)] = result
78             return result
79         return copy.deepcopy(self._wrapped, memo)
时间: 2024-10-21 19:30:40

好代码系列(一):LazyObject的相关文章

老二牛车Axure夜话: Axure嵌入代码系列视频教程汇总贴

老二牛车Axure夜话: Axure嵌入代码系列视频教程汇总贴 Axure嵌入代码系列视频教程汇总贴 嵌入代码系列视频教程之QQ一键加群 嵌入代码系列视频教程之新浪微博秀 嵌入代码系列视频教程之腾讯微博秀 嵌入代码系列视频教程之嵌入百度分享 嵌入代码系列视频教程之嵌入视频 嵌入代码系列视频教程之嵌入百度地图

iOS开发一行代码系列:一行搞定输入框

最近总结了下开发过程中常用的功能,发现有时候我在做重复性的劳动.于是决定把常用的功能抽出来,方便下次使用. 我的想法是:用最少的代码来解决问题.于是写了一些常用的工具类,名字就叫一行代码系列吧...好像挺挫的.. 大致内容有: 1.一行搞定输入框 2.一行搞定网络请求 3.一行搞定上下拉刷新(会自动判断是上拉还是下拉还是两者并存) 4.一行搞定数据库(最近还在写,功能已经基本实现) 5.一行搞定图片保存 6.一行搞定定位 7.一行搞定网络状况变化 8.一行搞定X(功能小集合) 一行搞定输入框 输

自适应大邻域搜索代码系列之(1) - 使用ALNS代码框架求解TSP问题

前言 上次出了邻域搜索的各种概念科普,尤其是LNS和ALNS的具体过程更是描述得一清二楚.不知道你萌都懂了吗?小编相信大家早就get到啦.不过有个别不愿意透露姓名的热心网友表示上次没有代码,遂不过瘾啊~哎,大家先别急,代码有得你们酸爽的-- 不过由于ALNS的代码量实在太大,小编打算把这个做成一个系列来一一为大家讲解,好让小伙伴们彻底把这个算法框架的代码吃透.今天暂时还是先不对代码进行讲解,先来教大家怎么使用ALNS的框架求解一个TSP问题吧~ 环境准备 小编的演示是基于Windows 10 x

整洁代码系列(1)

1.首先我们必须要了解糟糕的代码会导致什么问题? 越糟糕的代码,别人理解的时间就越长,会导致进度严重滞后(代码不仅仅是写给自己看的,除了自己,团队的其他成员也需要在必要的时候去理解): 越糟糕的代码,每次添加或修改代码,如果再不改变糟糕行为的前提下,代码回越来越烂,再也无法理清,最后会束手无策: 随着混乱的增加,团队的生产力会持续的下降,最后趋向于零. 当生产力下降时,管理层只会做一件事,就是增加更多的人手到项目中,期望提升生产力,可是新人并不熟悉系统的设计,但却背负着提升生产力的可怕压力,于是

每天看一片代码系列(四):layzr.js,处理图片懒加载的库

所谓图片的懒加载,即只有当图片处于或者接近于当前视窗时才开始加载图片.该库的使用方法非常简单: var layzr = new Layzr({ attr: 'data-layzr', // attr和retinaAttr必须至少有一个,用于指定对应的图片 retinaAttr: 'data-layzr-retina', // 一般对应的图像比attr要高清 threshold: 0, // 距离视窗的距离为多少时开始加载 callback: null // 回调函数 }); 代码解析 首先是包装

每天看一片代码系列(一):stream.js

简介 stream.js是一个小型的js库,用于处理stream相关的操作.这里的stream是指一种数据结构,它像数组一样,可以放置多个类型的数据,但是并不限制长度,甚至可以达到无限长.可以对该数据结构进行检索.修改.追加等种种操作.由于其长度不限这一特性,使得它与通常意义下的数据结构有明显的区别. API stream提供的API包含三种. 第一种是创建类.包括: new Stream(head, functionReturingTail) 第二个参数是一个放回除第一个元素之外剩下的元素的方

iOS开发一行代码系列:一行搞定输入框优化

iOS8以前,我们设置键盘为UIKeyboardTypeNumberPad类型的,我们就不太容易输入字母或者其他的.iOS8以后,由于支持了第三方输入法,就算设置键盘为UIKeyboardTypeNumberPad类型的,我们随便切换下就很容易输入其他字母啦.为了解决这样的问题,我们对InputHelper进行优化,这样以后我们就不用为这样的小问题浪费时间了.常见的小问题还有,评论字数的限制,如果超过120字可能会做截取或者弹出提示框:或者不能输入空格:或者只能输入英文. 源码下载地址:inpu

奇妙JS代码系列(二)call,apply,bind用处整理

延续系列一:链接,此次主要整理JS里面很常见的三个函数call,apply,bind的妙用.(apply和call差不多,只是参数的区别)(下面有些这三个可能只是辅助,但是只要用到,我就在这里整理) 1.类型检测 上一篇最后一个已经讲到,Object.prototype.toString.call().犹豫上一篇说了,这里就不多说了. 2.解参,等同于ES6中的...扩展运算符 es6中提出了一种很方便解构字符串数组的运算符,这提供了一种简便机制,可以将任何部署了 Iterator 接口的数据结

纯代码系列:Python实现验证码图片(PIL库经典用法用法,爬虫12306思路)

现在的网页中,为了防止机器人提交表单,图片验证码是很常见的应对手段之一.这里就不详细介绍了,相信大家都遇到过. 现在就给出用Python的PIL库实现验证码图片的代码.代码中有详细注释. #!/usr/bin/env python #coding=utf-8 import random from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小