django LazyObject类研究

class LazyObject(object):
    """
    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):
        self._wrapped = empty

    __getattr__ = new_method_proxy(getattr)

    def __setattr__(self, name, value):
        if name == "_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":
            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')


从介绍来说, 可以看出LazyObject的作用就是推迟包装类的实例化,即是需要用的时候,才实例化它。

对于理解这段代码,可以从实际适用来入手。我们只需指定一个要使用的类,传给LazyObject,那么我们

使用LazyObject,就如同使用包装类一样。这种设计,应该是对用户透明的。

当我们使用类时,分为获取属性,添加属性,删除属性。

对应的三种方法,__getatrr__, __setatrr__, __delatrr__。

在python中对三种方法的重载,就可以实现上述的效果。即LazyObject与包装类是透明的。

在LazyObject的三种方法的实现中, 可以看出推迟实例化的实现。

即先判断包装类是否已经实例化,否则实例它(通过实现_setup()方法实现)。


注意到__getattr__方法,是通过 new_method_proxy函数实现的。

new_method_proxy其实是工厂函数。目的也是推迟实例化。

def new_method_proxy(func):
    def inner(self, *args):
        if self._wrapped is empty:
            self._setup()
        return func(self._wrapped, *args)
    return inner

转载于:https://my.oschina.net/u/569730/blog/339906

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值